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/* We define this here to remove any further warnings about the usage of 26 deprecated functions in this file. */ 27#define SVN_DEPRECATED 28 29#include <apr_md5.h> 30 31#include "svn_wc.h" 32#include "svn_subst.h" 33#include "svn_pools.h" 34#include "svn_props.h" 35#include "svn_hash.h" 36#include "svn_time.h" 37#include "svn_dirent_uri.h" 38#include "svn_path.h" 39 40#include "private/svn_subr_private.h" 41#include "private/svn_wc_private.h" 42 43#include "wc.h" 44#include "entries.h" 45#include "lock.h" 46#include "props.h" 47#include "translate.h" 48#include "workqueue.h" 49 50#include "svn_private_config.h" 51 52/* baton for traversal_info_update */ 53struct traversal_info_update_baton 54{ 55 struct svn_wc_traversal_info_t *traversal; 56 svn_wc__db_t *db; 57}; 58 59/* Helper for updating svn_wc_traversal_info_t structures 60 * Implements svn_wc_external_update_t */ 61static svn_error_t * 62traversal_info_update(void *baton, 63 const char *local_abspath, 64 const svn_string_t *old_val, 65 const svn_string_t *new_val, 66 svn_depth_t depth, 67 apr_pool_t *scratch_pool) 68{ 69 const char *dup_path; 70 svn_wc_adm_access_t *adm_access; 71 struct traversal_info_update_baton *ub = baton; 72 apr_pool_t *dup_pool = ub->traversal->pool; 73 const char *dup_val = NULL; 74 75 /* We make the abspath relative by retrieving the access baton 76 for the specific directory */ 77 adm_access = svn_wc__adm_retrieve_internal2(ub->db, local_abspath, 78 scratch_pool); 79 80 if (adm_access) 81 dup_path = apr_pstrdup(dup_pool, svn_wc_adm_access_path(adm_access)); 82 else 83 dup_path = apr_pstrdup(dup_pool, local_abspath); 84 85 if (old_val) 86 { 87 dup_val = apr_pstrmemdup(dup_pool, old_val->data, old_val->len); 88 89 svn_hash_sets(ub->traversal->externals_old, dup_path, dup_val); 90 } 91 92 if (new_val) 93 { 94 /* In most cases the value is identical */ 95 if (old_val != new_val) 96 dup_val = apr_pstrmemdup(dup_pool, new_val->data, new_val->len); 97 98 svn_hash_sets(ub->traversal->externals_new, dup_path, dup_val); 99 } 100 101 svn_hash_sets(ub->traversal->depths, dup_path, svn_depth_to_word(depth)); 102 103 return SVN_NO_ERROR; 104} 105 106/* Helper for functions that used to gather traversal_info */ 107static svn_error_t * 108gather_traversal_info(svn_wc_context_t *wc_ctx, 109 const char *local_abspath, 110 const char *path, 111 svn_depth_t depth, 112 struct svn_wc_traversal_info_t *traversal_info, 113 svn_boolean_t gather_as_old, 114 svn_boolean_t gather_as_new, 115 apr_pool_t *scratch_pool) 116{ 117 apr_hash_t *externals; 118 apr_hash_t *ambient_depths; 119 apr_hash_index_t *hi; 120 121 SVN_ERR(svn_wc__externals_gather_definitions(&externals, &ambient_depths, 122 wc_ctx, local_abspath, 123 depth, 124 scratch_pool, scratch_pool)); 125 126 for (hi = apr_hash_first(scratch_pool, externals); 127 hi; 128 hi = apr_hash_next(hi)) 129 { 130 const char *node_abspath = apr_hash_this_key(hi); 131 const char *relpath; 132 133 relpath = svn_dirent_join(path, 134 svn_dirent_skip_ancestor(local_abspath, 135 node_abspath), 136 traversal_info->pool); 137 138 if (gather_as_old) 139 svn_hash_sets(traversal_info->externals_old, relpath, 140 apr_hash_this_val(hi)); 141 142 if (gather_as_new) 143 svn_hash_sets(traversal_info->externals_new, relpath, 144 apr_hash_this_val(hi)); 145 146 svn_hash_sets(traversal_info->depths, relpath, 147 svn_hash_gets(ambient_depths, node_abspath)); 148 } 149 150 return SVN_NO_ERROR; 151} 152 153 154/*** From adm_crawler.c ***/ 155 156svn_error_t * 157svn_wc_crawl_revisions4(const char *path, 158 svn_wc_adm_access_t *adm_access, 159 const svn_ra_reporter3_t *reporter, 160 void *report_baton, 161 svn_boolean_t restore_files, 162 svn_depth_t depth, 163 svn_boolean_t honor_depth_exclude, 164 svn_boolean_t depth_compatibility_trick, 165 svn_boolean_t use_commit_times, 166 svn_wc_notify_func2_t notify_func, 167 void *notify_baton, 168 svn_wc_traversal_info_t *traversal_info, 169 apr_pool_t *pool) 170{ 171 svn_wc_context_t *wc_ctx; 172 svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access); 173 const char *local_abspath; 174 175 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 176 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 177 178 SVN_ERR(svn_wc_crawl_revisions5(wc_ctx, 179 local_abspath, 180 reporter, 181 report_baton, 182 restore_files, 183 depth, 184 honor_depth_exclude, 185 depth_compatibility_trick, 186 use_commit_times, 187 NULL /* cancel_func */, 188 NULL /* cancel_baton */, 189 notify_func, 190 notify_baton, 191 pool)); 192 193 if (traversal_info) 194 SVN_ERR(gather_traversal_info(wc_ctx, local_abspath, path, depth, 195 traversal_info, TRUE, FALSE, pool)); 196 197 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 198} 199 200/*** Compatibility wrapper: turns an svn_ra_reporter2_t into an 201 svn_ra_reporter3_t. 202 203 This code looks like it duplicates code in libsvn_ra/ra_loader.c, 204 but it does not. That code makes an new thing look like an old 205 thing; this code makes an old thing look like a new thing. ***/ 206 207struct wrap_3to2_report_baton { 208 const svn_ra_reporter2_t *reporter; 209 void *baton; 210}; 211 212/* */ 213static svn_error_t *wrap_3to2_set_path(void *report_baton, 214 const char *path, 215 svn_revnum_t revision, 216 svn_depth_t depth, 217 svn_boolean_t start_empty, 218 const char *lock_token, 219 apr_pool_t *pool) 220{ 221 struct wrap_3to2_report_baton *wrb = report_baton; 222 223 return wrb->reporter->set_path(wrb->baton, path, revision, start_empty, 224 lock_token, pool); 225} 226 227/* */ 228static svn_error_t *wrap_3to2_delete_path(void *report_baton, 229 const char *path, 230 apr_pool_t *pool) 231{ 232 struct wrap_3to2_report_baton *wrb = report_baton; 233 234 return wrb->reporter->delete_path(wrb->baton, path, pool); 235} 236 237/* */ 238static svn_error_t *wrap_3to2_link_path(void *report_baton, 239 const char *path, 240 const char *url, 241 svn_revnum_t revision, 242 svn_depth_t depth, 243 svn_boolean_t start_empty, 244 const char *lock_token, 245 apr_pool_t *pool) 246{ 247 struct wrap_3to2_report_baton *wrb = report_baton; 248 249 return wrb->reporter->link_path(wrb->baton, path, url, revision, 250 start_empty, lock_token, pool); 251} 252 253/* */ 254static svn_error_t *wrap_3to2_finish_report(void *report_baton, 255 apr_pool_t *pool) 256{ 257 struct wrap_3to2_report_baton *wrb = report_baton; 258 259 return wrb->reporter->finish_report(wrb->baton, pool); 260} 261 262/* */ 263static svn_error_t *wrap_3to2_abort_report(void *report_baton, 264 apr_pool_t *pool) 265{ 266 struct wrap_3to2_report_baton *wrb = report_baton; 267 268 return wrb->reporter->abort_report(wrb->baton, pool); 269} 270 271static const svn_ra_reporter3_t wrap_3to2_reporter = { 272 wrap_3to2_set_path, 273 wrap_3to2_delete_path, 274 wrap_3to2_link_path, 275 wrap_3to2_finish_report, 276 wrap_3to2_abort_report 277}; 278 279svn_error_t * 280svn_wc_crawl_revisions3(const char *path, 281 svn_wc_adm_access_t *adm_access, 282 const svn_ra_reporter3_t *reporter, 283 void *report_baton, 284 svn_boolean_t restore_files, 285 svn_depth_t depth, 286 svn_boolean_t depth_compatibility_trick, 287 svn_boolean_t use_commit_times, 288 svn_wc_notify_func2_t notify_func, 289 void *notify_baton, 290 svn_wc_traversal_info_t *traversal_info, 291 apr_pool_t *pool) 292{ 293 return svn_wc_crawl_revisions4(path, 294 adm_access, 295 reporter, report_baton, 296 restore_files, 297 depth, 298 FALSE, 299 depth_compatibility_trick, 300 use_commit_times, 301 notify_func, 302 notify_baton, 303 traversal_info, 304 pool); 305} 306 307svn_error_t * 308svn_wc_crawl_revisions2(const char *path, 309 svn_wc_adm_access_t *adm_access, 310 const svn_ra_reporter2_t *reporter, 311 void *report_baton, 312 svn_boolean_t restore_files, 313 svn_boolean_t recurse, 314 svn_boolean_t use_commit_times, 315 svn_wc_notify_func2_t notify_func, 316 void *notify_baton, 317 svn_wc_traversal_info_t *traversal_info, 318 apr_pool_t *pool) 319{ 320 struct wrap_3to2_report_baton wrb; 321 wrb.reporter = reporter; 322 wrb.baton = report_baton; 323 324 return svn_wc_crawl_revisions3(path, 325 adm_access, 326 &wrap_3to2_reporter, &wrb, 327 restore_files, 328 SVN_DEPTH_INFINITY_OR_FILES(recurse), 329 FALSE, 330 use_commit_times, 331 notify_func, 332 notify_baton, 333 traversal_info, 334 pool); 335} 336 337 338/* Baton for compat_call_notify_func below. */ 339struct compat_notify_baton_t { 340 /* Wrapped func/baton. */ 341 svn_wc_notify_func_t func; 342 void *baton; 343}; 344 345 346/* Implements svn_wc_notify_func2_t. Call BATON->func (BATON is of type 347 svn_wc__compat_notify_baton_t), passing BATON->baton and the appropriate 348 arguments from NOTIFY. */ 349static void 350compat_call_notify_func(void *baton, 351 const svn_wc_notify_t *n, 352 apr_pool_t *pool) 353{ 354 struct compat_notify_baton_t *nb = baton; 355 356 if (nb->func) 357 (*nb->func)(nb->baton, n->path, n->action, n->kind, n->mime_type, 358 n->content_state, n->prop_state, n->revision); 359} 360 361 362/*** Compatibility wrapper: turns an svn_ra_reporter_t into an 363 svn_ra_reporter2_t. 364 365 This code looks like it duplicates code in libsvn_ra/ra_loader.c, 366 but it does not. That code makes an new thing look like an old 367 thing; this code makes an old thing look like a new thing. ***/ 368 369struct wrap_2to1_report_baton { 370 const svn_ra_reporter_t *reporter; 371 void *baton; 372}; 373 374/* */ 375static svn_error_t *wrap_2to1_set_path(void *report_baton, 376 const char *path, 377 svn_revnum_t revision, 378 svn_boolean_t start_empty, 379 const char *lock_token, 380 apr_pool_t *pool) 381{ 382 struct wrap_2to1_report_baton *wrb = report_baton; 383 384 return wrb->reporter->set_path(wrb->baton, path, revision, start_empty, 385 pool); 386} 387 388/* */ 389static svn_error_t *wrap_2to1_delete_path(void *report_baton, 390 const char *path, 391 apr_pool_t *pool) 392{ 393 struct wrap_2to1_report_baton *wrb = report_baton; 394 395 return wrb->reporter->delete_path(wrb->baton, path, pool); 396} 397 398/* */ 399static svn_error_t *wrap_2to1_link_path(void *report_baton, 400 const char *path, 401 const char *url, 402 svn_revnum_t revision, 403 svn_boolean_t start_empty, 404 const char *lock_token, 405 apr_pool_t *pool) 406{ 407 struct wrap_2to1_report_baton *wrb = report_baton; 408 409 return wrb->reporter->link_path(wrb->baton, path, url, revision, 410 start_empty, pool); 411} 412 413/* */ 414static svn_error_t *wrap_2to1_finish_report(void *report_baton, 415 apr_pool_t *pool) 416{ 417 struct wrap_2to1_report_baton *wrb = report_baton; 418 419 return wrb->reporter->finish_report(wrb->baton, pool); 420} 421 422/* */ 423static svn_error_t *wrap_2to1_abort_report(void *report_baton, 424 apr_pool_t *pool) 425{ 426 struct wrap_2to1_report_baton *wrb = report_baton; 427 428 return wrb->reporter->abort_report(wrb->baton, pool); 429} 430 431static const svn_ra_reporter2_t wrap_2to1_reporter = { 432 wrap_2to1_set_path, 433 wrap_2to1_delete_path, 434 wrap_2to1_link_path, 435 wrap_2to1_finish_report, 436 wrap_2to1_abort_report 437}; 438 439svn_error_t * 440svn_wc_crawl_revisions(const char *path, 441 svn_wc_adm_access_t *adm_access, 442 const svn_ra_reporter_t *reporter, 443 void *report_baton, 444 svn_boolean_t restore_files, 445 svn_boolean_t recurse, 446 svn_boolean_t use_commit_times, 447 svn_wc_notify_func_t notify_func, 448 void *notify_baton, 449 svn_wc_traversal_info_t *traversal_info, 450 apr_pool_t *pool) 451{ 452 struct wrap_2to1_report_baton wrb; 453 struct compat_notify_baton_t nb; 454 455 wrb.reporter = reporter; 456 wrb.baton = report_baton; 457 458 nb.func = notify_func; 459 nb.baton = notify_baton; 460 461 return svn_wc_crawl_revisions2(path, adm_access, &wrap_2to1_reporter, &wrb, 462 restore_files, recurse, use_commit_times, 463 compat_call_notify_func, &nb, 464 traversal_info, 465 pool); 466} 467 468svn_error_t * 469svn_wc_transmit_text_deltas2(const char **tempfile, 470 unsigned char digest[], 471 const char *path, 472 svn_wc_adm_access_t *adm_access, 473 svn_boolean_t fulltext, 474 const svn_delta_editor_t *editor, 475 void *file_baton, 476 apr_pool_t *pool) 477{ 478 const char *local_abspath; 479 svn_wc_context_t *wc_ctx; 480 const svn_checksum_t *new_text_base_md5_checksum; 481 482 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 483 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 484 svn_wc__adm_get_db(adm_access), 485 pool)); 486 487 SVN_ERR(svn_wc__internal_transmit_text_deltas(tempfile, 488 (digest 489 ? &new_text_base_md5_checksum 490 : NULL), 491 NULL, wc_ctx->db, 492 local_abspath, fulltext, 493 editor, file_baton, 494 pool, pool)); 495 496 if (digest) 497 memcpy(digest, new_text_base_md5_checksum->digest, APR_MD5_DIGESTSIZE); 498 499 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 500} 501 502svn_error_t * 503svn_wc_transmit_text_deltas(const char *path, 504 svn_wc_adm_access_t *adm_access, 505 svn_boolean_t fulltext, 506 const svn_delta_editor_t *editor, 507 void *file_baton, 508 const char **tempfile, 509 apr_pool_t *pool) 510{ 511 return svn_wc_transmit_text_deltas2(tempfile, NULL, path, adm_access, 512 fulltext, editor, file_baton, pool); 513} 514 515svn_error_t * 516svn_wc_transmit_prop_deltas(const char *path, 517 svn_wc_adm_access_t *adm_access, 518 const svn_wc_entry_t *entry, 519 const svn_delta_editor_t *editor, 520 void *baton, 521 const char **tempfile, 522 apr_pool_t *pool) 523{ 524 const char *local_abspath; 525 svn_wc_context_t *wc_ctx; 526 527 if (tempfile) 528 *tempfile = NULL; 529 530 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 531 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 532 svn_wc__adm_get_db(adm_access), 533 pool)); 534 535 SVN_ERR(svn_wc_transmit_prop_deltas2(wc_ctx, local_abspath, editor, baton, 536 pool)); 537 538 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 539} 540 541/*** From adm_files.c ***/ 542svn_error_t * 543svn_wc_ensure_adm3(const char *path, 544 const char *uuid, 545 const char *url, 546 const char *repos, 547 svn_revnum_t revision, 548 svn_depth_t depth, 549 apr_pool_t *pool) 550{ 551 const char *local_abspath; 552 svn_wc_context_t *wc_ctx; 553 554 if (uuid == NULL) 555 return svn_error_create(SVN_ERR_BAD_UUID, NULL, NULL); 556 if (repos == NULL) 557 return svn_error_create(SVN_ERR_BAD_URL, NULL, NULL); 558 559 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 560 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL /* config */, pool, pool)); 561 562 SVN_ERR(svn_wc_ensure_adm4(wc_ctx, local_abspath, url, repos, uuid, revision, 563 depth, pool)); 564 565 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 566} 567 568svn_error_t * 569svn_wc_ensure_adm2(const char *path, 570 const char *uuid, 571 const char *url, 572 const char *repos, 573 svn_revnum_t revision, 574 apr_pool_t *pool) 575{ 576 return svn_wc_ensure_adm3(path, uuid, url, repos, revision, 577 svn_depth_infinity, pool); 578} 579 580 581svn_error_t * 582svn_wc_ensure_adm(const char *path, 583 const char *uuid, 584 const char *url, 585 svn_revnum_t revision, 586 apr_pool_t *pool) 587{ 588 return svn_wc_ensure_adm2(path, uuid, url, NULL, revision, pool); 589} 590 591svn_error_t * 592svn_wc_create_tmp_file(apr_file_t **fp, 593 const char *path, 594 svn_boolean_t delete_on_close, 595 apr_pool_t *pool) 596{ 597 return svn_wc_create_tmp_file2(fp, NULL, path, 598 delete_on_close 599 ? svn_io_file_del_on_close 600 : svn_io_file_del_none, 601 pool); 602} 603 604svn_error_t * 605svn_wc_create_tmp_file2(apr_file_t **fp, 606 const char **new_name, 607 const char *path, 608 svn_io_file_del_t delete_when, 609 apr_pool_t *pool) 610{ 611 svn_wc_context_t *wc_ctx; 612 const char *local_abspath; 613 const char *temp_dir; 614 svn_error_t *err; 615 616 SVN_ERR_ASSERT(fp || new_name); 617 618 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL /* config */, pool, pool)); 619 620 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 621 err = svn_wc__get_tmpdir(&temp_dir, wc_ctx, local_abspath, pool, pool); 622 err = svn_error_compose_create(err, svn_wc_context_destroy(wc_ctx)); 623 if (err) 624 return svn_error_trace(err); 625 626 SVN_ERR(svn_io_open_unique_file3(fp, new_name, temp_dir, 627 delete_when, pool, pool)); 628 629 return SVN_NO_ERROR; 630} 631 632 633/*** From adm_ops.c ***/ 634svn_error_t * 635svn_wc_get_pristine_contents(svn_stream_t **contents, 636 const char *path, 637 apr_pool_t *result_pool, 638 apr_pool_t *scratch_pool) 639{ 640 svn_wc_context_t *wc_ctx; 641 const char *local_abspath; 642 643 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool, scratch_pool)); 644 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool)); 645 646 SVN_ERR(svn_wc_get_pristine_contents2(contents, 647 wc_ctx, 648 local_abspath, 649 result_pool, 650 scratch_pool)); 651 652 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 653} 654 655svn_error_t * 656svn_wc_queue_committed3(svn_wc_committed_queue_t *queue, 657 svn_wc_context_t *wc_ctx, 658 const char *local_abspath, 659 svn_boolean_t recurse, 660 const apr_array_header_t *wcprop_changes, 661 svn_boolean_t remove_lock, 662 svn_boolean_t remove_changelist, 663 const svn_checksum_t *sha1_checksum, 664 apr_pool_t *scratch_pool) 665{ 666 return svn_error_trace( 667 svn_wc_queue_committed4(queue, wc_ctx, local_abspath, 668 recurse, TRUE /* is_committed */, 669 wcprop_changes, remove_lock, 670 remove_changelist, sha1_checksum, 671 scratch_pool)); 672} 673 674svn_error_t * 675svn_wc_queue_committed2(svn_wc_committed_queue_t *queue, 676 const char *path, 677 svn_wc_adm_access_t *adm_access, 678 svn_boolean_t recurse, 679 const apr_array_header_t *wcprop_changes, 680 svn_boolean_t remove_lock, 681 svn_boolean_t remove_changelist, 682 const svn_checksum_t *md5_checksum, 683 apr_pool_t *scratch_pool) 684{ 685 svn_wc_context_t *wc_ctx; 686 const char *local_abspath; 687 const svn_checksum_t *sha1_checksum = NULL; 688 689 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, 690 svn_wc__adm_get_db(adm_access), 691 scratch_pool)); 692 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool)); 693 694 if (md5_checksum != NULL) 695 { 696 svn_error_t *err; 697 err = svn_wc__db_pristine_get_sha1(&sha1_checksum, wc_ctx->db, 698 local_abspath, md5_checksum, 699 svn_wc__get_committed_queue_pool(queue), 700 scratch_pool); 701 702 /* Don't fail on SHA1 not found */ 703 if (err && err->apr_err == SVN_ERR_WC_DB_ERROR) 704 { 705 svn_error_clear(err); 706 sha1_checksum = NULL; 707 } 708 else 709 SVN_ERR(err); 710 } 711 712 SVN_ERR(svn_wc_queue_committed3(queue, wc_ctx, local_abspath, recurse, 713 wcprop_changes, 714 remove_lock, remove_changelist, 715 sha1_checksum, scratch_pool)); 716 717 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 718} 719 720svn_error_t * 721svn_wc_queue_committed(svn_wc_committed_queue_t **queue, 722 const char *path, 723 svn_wc_adm_access_t *adm_access, 724 svn_boolean_t recurse, 725 const apr_array_header_t *wcprop_changes, 726 svn_boolean_t remove_lock, 727 svn_boolean_t remove_changelist, 728 const unsigned char *digest, 729 apr_pool_t *pool) 730{ 731 const svn_checksum_t *md5_checksum; 732 733 if (digest) 734 md5_checksum = svn_checksum__from_digest_md5( 735 digest, svn_wc__get_committed_queue_pool(*queue)); 736 else 737 md5_checksum = NULL; 738 739 return svn_wc_queue_committed2(*queue, path, adm_access, recurse, 740 wcprop_changes, remove_lock, 741 remove_changelist, md5_checksum, pool); 742} 743 744svn_error_t * 745svn_wc_process_committed_queue(svn_wc_committed_queue_t *queue, 746 svn_wc_adm_access_t *adm_access, 747 svn_revnum_t new_revnum, 748 const char *rev_date, 749 const char *rev_author, 750 apr_pool_t *pool) 751{ 752 svn_wc_context_t *wc_ctx; 753 754 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, 755 svn_wc__adm_get_db(adm_access), 756 pool)); 757 SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, new_revnum, 758 rev_date, rev_author, 759 NULL, NULL, pool)); 760 SVN_ERR(svn_wc_context_destroy(wc_ctx)); 761 762 return SVN_NO_ERROR; 763} 764 765svn_error_t * 766svn_wc_process_committed4(const char *path, 767 svn_wc_adm_access_t *adm_access, 768 svn_boolean_t recurse, 769 svn_revnum_t new_revnum, 770 const char *rev_date, 771 const char *rev_author, 772 const apr_array_header_t *wcprop_changes, 773 svn_boolean_t remove_lock, 774 svn_boolean_t remove_changelist, 775 const unsigned char *digest, 776 apr_pool_t *pool) 777{ 778 svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); 779 const char *local_abspath; 780 const svn_checksum_t *md5_checksum; 781 const svn_checksum_t *sha1_checksum = NULL; 782 svn_wc_context_t *wc_ctx; 783 svn_wc_committed_queue_t *queue; 784 785 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 786 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 787 788 if (digest) 789 md5_checksum = svn_checksum__from_digest_md5(digest, pool); 790 else 791 md5_checksum = NULL; 792 793 if (md5_checksum != NULL) 794 { 795 svn_error_t *err; 796 err = svn_wc__db_pristine_get_sha1(&sha1_checksum, db, 797 local_abspath, md5_checksum, 798 pool, pool); 799 800 if (err && err->apr_err == SVN_ERR_WC_DB_ERROR) 801 { 802 svn_error_clear(err); 803 sha1_checksum = NULL; 804 } 805 else 806 SVN_ERR(err); 807 } 808 809 queue = svn_wc_committed_queue_create(pool); 810 SVN_ERR(svn_wc_queue_committed3(queue, wc_ctx, local_abspath, recurse, 811 wcprop_changes, remove_lock, 812 remove_changelist, 813 sha1_checksum /* or NULL if not modified 814 or directory */, 815 pool)); 816 817 SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, 818 new_revnum, rev_date, rev_author, 819 NULL, NULL /* cancel */, 820 pool)); 821 822 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 823} 824 825 826svn_error_t * 827svn_wc_process_committed3(const char *path, 828 svn_wc_adm_access_t *adm_access, 829 svn_boolean_t recurse, 830 svn_revnum_t new_revnum, 831 const char *rev_date, 832 const char *rev_author, 833 const apr_array_header_t *wcprop_changes, 834 svn_boolean_t remove_lock, 835 const unsigned char *digest, 836 apr_pool_t *pool) 837{ 838 return svn_wc_process_committed4(path, adm_access, recurse, new_revnum, 839 rev_date, rev_author, wcprop_changes, 840 remove_lock, FALSE, digest, pool); 841} 842 843svn_error_t * 844svn_wc_process_committed2(const char *path, 845 svn_wc_adm_access_t *adm_access, 846 svn_boolean_t recurse, 847 svn_revnum_t new_revnum, 848 const char *rev_date, 849 const char *rev_author, 850 const apr_array_header_t *wcprop_changes, 851 svn_boolean_t remove_lock, 852 apr_pool_t *pool) 853{ 854 return svn_wc_process_committed3(path, adm_access, recurse, new_revnum, 855 rev_date, rev_author, wcprop_changes, 856 remove_lock, NULL, pool); 857} 858 859svn_error_t * 860svn_wc_process_committed(const char *path, 861 svn_wc_adm_access_t *adm_access, 862 svn_boolean_t recurse, 863 svn_revnum_t new_revnum, 864 const char *rev_date, 865 const char *rev_author, 866 const apr_array_header_t *wcprop_changes, 867 apr_pool_t *pool) 868{ 869 return svn_wc_process_committed2(path, adm_access, recurse, new_revnum, 870 rev_date, rev_author, wcprop_changes, 871 FALSE, pool); 872} 873 874svn_error_t * 875svn_wc_maybe_set_repos_root(svn_wc_adm_access_t *adm_access, 876 const char *path, 877 const char *repos, 878 apr_pool_t *pool) 879{ 880 return SVN_NO_ERROR; 881} 882 883svn_error_t * 884svn_wc_delete3(const char *path, 885 svn_wc_adm_access_t *adm_access, 886 svn_cancel_func_t cancel_func, 887 void *cancel_baton, 888 svn_wc_notify_func2_t notify_func, 889 void *notify_baton, 890 svn_boolean_t keep_local, 891 apr_pool_t *pool) 892{ 893 svn_wc_context_t *wc_ctx; 894 svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access); 895 svn_wc_adm_access_t *dir_access; 896 const char *local_abspath; 897 898 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 899 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 900 901 /* Open access batons for everything below path, because we used to open 902 these before. */ 903 SVN_ERR(svn_wc_adm_probe_try3(&dir_access, adm_access, path, 904 TRUE, -1, cancel_func, cancel_baton, pool)); 905 906 SVN_ERR(svn_wc_delete4(wc_ctx, 907 local_abspath, 908 keep_local, 909 TRUE, 910 cancel_func, cancel_baton, 911 notify_func, notify_baton, 912 pool)); 913 914 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 915} 916 917svn_error_t * 918svn_wc_delete2(const char *path, 919 svn_wc_adm_access_t *adm_access, 920 svn_cancel_func_t cancel_func, 921 void *cancel_baton, 922 svn_wc_notify_func2_t notify_func, 923 void *notify_baton, 924 apr_pool_t *pool) 925{ 926 return svn_wc_delete3(path, adm_access, cancel_func, cancel_baton, 927 notify_func, notify_baton, FALSE, pool); 928} 929 930svn_error_t * 931svn_wc_delete(const char *path, 932 svn_wc_adm_access_t *adm_access, 933 svn_cancel_func_t cancel_func, 934 void *cancel_baton, 935 svn_wc_notify_func_t notify_func, 936 void *notify_baton, 937 apr_pool_t *pool) 938{ 939 struct compat_notify_baton_t nb; 940 941 nb.func = notify_func; 942 nb.baton = notify_baton; 943 944 return svn_wc_delete2(path, adm_access, cancel_func, cancel_baton, 945 compat_call_notify_func, &nb, pool); 946} 947 948svn_error_t * 949svn_wc_add_from_disk2(svn_wc_context_t *wc_ctx, 950 const char *local_abspath, 951 const apr_hash_t *props, 952 svn_wc_notify_func2_t notify_func, 953 void *notify_baton, 954 apr_pool_t *scratch_pool) 955{ 956 SVN_ERR(svn_wc_add_from_disk3(wc_ctx, local_abspath, props, FALSE, 957 notify_func, notify_baton, scratch_pool)); 958 return SVN_NO_ERROR; 959} 960 961svn_error_t * 962svn_wc_add_from_disk(svn_wc_context_t *wc_ctx, 963 const char *local_abspath, 964 svn_wc_notify_func2_t notify_func, 965 void *notify_baton, 966 apr_pool_t *scratch_pool) 967{ 968 SVN_ERR(svn_wc_add_from_disk2(wc_ctx, local_abspath, NULL, 969 notify_func, notify_baton, scratch_pool)); 970 return SVN_NO_ERROR; 971} 972 973svn_error_t * 974svn_wc_add3(const char *path, 975 svn_wc_adm_access_t *parent_access, 976 svn_depth_t depth, 977 const char *copyfrom_url, 978 svn_revnum_t copyfrom_rev, 979 svn_cancel_func_t cancel_func, 980 void *cancel_baton, 981 svn_wc_notify_func2_t notify_func, 982 void *notify_baton, 983 apr_pool_t *pool) 984{ 985 svn_wc_context_t *wc_ctx; 986 svn_wc__db_t *wc_db = svn_wc__adm_get_db(parent_access); 987 const char *local_abspath; 988 989 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 990 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 991 992 SVN_ERR(svn_wc_add4(wc_ctx, local_abspath, 993 depth, copyfrom_url, 994 copyfrom_rev, 995 cancel_func, cancel_baton, 996 notify_func, notify_baton, pool)); 997 998 /* Make sure the caller gets the new access baton in the set. */ 999 if (svn_wc__adm_retrieve_internal2(wc_db, local_abspath, pool) == NULL) 1000 { 1001 svn_node_kind_t kind; 1002 1003 SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath, 1004 FALSE /* allow_missing */, 1005 TRUE /* show_deleted */, 1006 FALSE /* show_hidden */, pool)); 1007 if (kind == svn_node_dir) 1008 { 1009 svn_wc_adm_access_t *adm_access; 1010 1011 /* Open the access baton in adm_access' pool to give it the same 1012 lifetime */ 1013 SVN_ERR(svn_wc_adm_open3(&adm_access, parent_access, path, TRUE, 1014 copyfrom_url ? -1 : 0, 1015 cancel_func, cancel_baton, 1016 svn_wc_adm_access_pool(parent_access))); 1017 } 1018 } 1019 1020 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1021} 1022 1023 1024svn_error_t * 1025svn_wc_add2(const char *path, 1026 svn_wc_adm_access_t *parent_access, 1027 const char *copyfrom_url, 1028 svn_revnum_t copyfrom_rev, 1029 svn_cancel_func_t cancel_func, 1030 void *cancel_baton, 1031 svn_wc_notify_func2_t notify_func, 1032 void *notify_baton, 1033 apr_pool_t *pool) 1034{ 1035 return svn_wc_add3(path, parent_access, svn_depth_infinity, 1036 copyfrom_url, copyfrom_rev, 1037 cancel_func, cancel_baton, 1038 notify_func, notify_baton, pool); 1039} 1040 1041svn_error_t * 1042svn_wc_add(const char *path, 1043 svn_wc_adm_access_t *parent_access, 1044 const char *copyfrom_url, 1045 svn_revnum_t copyfrom_rev, 1046 svn_cancel_func_t cancel_func, 1047 void *cancel_baton, 1048 svn_wc_notify_func_t notify_func, 1049 void *notify_baton, 1050 apr_pool_t *pool) 1051{ 1052 struct compat_notify_baton_t nb; 1053 1054 nb.func = notify_func; 1055 nb.baton = notify_baton; 1056 1057 return svn_wc_add2(path, parent_access, copyfrom_url, copyfrom_rev, 1058 cancel_func, cancel_baton, 1059 compat_call_notify_func, &nb, pool); 1060} 1061 1062/*** From revert.c ***/ 1063svn_error_t * 1064svn_wc_revert4(svn_wc_context_t *wc_ctx, 1065 const char *local_abspath, 1066 svn_depth_t depth, 1067 svn_boolean_t use_commit_times, 1068 const apr_array_header_t *changelist_filter, 1069 svn_cancel_func_t cancel_func, 1070 void *cancel_baton, 1071 svn_wc_notify_func2_t notify_func, 1072 void *notify_baton, 1073 apr_pool_t *scratch_pool) 1074{ 1075 return svn_error_trace(svn_wc_revert5(wc_ctx, local_abspath, 1076 depth, 1077 use_commit_times, 1078 changelist_filter, 1079 FALSE /* clear_changelists */, 1080 FALSE /* metadata_only */, 1081 cancel_func, cancel_baton, 1082 notify_func, notify_baton, 1083 scratch_pool)); 1084} 1085 1086svn_error_t * 1087svn_wc_revert3(const char *path, 1088 svn_wc_adm_access_t *parent_access, 1089 svn_depth_t depth, 1090 svn_boolean_t use_commit_times, 1091 const apr_array_header_t *changelist_filter, 1092 svn_cancel_func_t cancel_func, 1093 void *cancel_baton, 1094 svn_wc_notify_func2_t notify_func, 1095 void *notify_baton, 1096 apr_pool_t *pool) 1097{ 1098 svn_wc_context_t *wc_ctx; 1099 svn_wc__db_t *wc_db = svn_wc__adm_get_db(parent_access); 1100 const char *local_abspath; 1101 1102 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 1103 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 1104 1105 SVN_ERR(svn_wc_revert4(wc_ctx, 1106 local_abspath, 1107 depth, 1108 use_commit_times, 1109 changelist_filter, 1110 cancel_func, cancel_baton, 1111 notify_func, notify_baton, 1112 pool)); 1113 1114 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1115} 1116 1117svn_error_t * 1118svn_wc_revert2(const char *path, 1119 svn_wc_adm_access_t *parent_access, 1120 svn_boolean_t recursive, 1121 svn_boolean_t use_commit_times, 1122 svn_cancel_func_t cancel_func, 1123 void *cancel_baton, 1124 svn_wc_notify_func2_t notify_func, 1125 void *notify_baton, 1126 apr_pool_t *pool) 1127{ 1128 return svn_wc_revert3(path, parent_access, 1129 SVN_DEPTH_INFINITY_OR_EMPTY(recursive), 1130 use_commit_times, NULL, cancel_func, cancel_baton, 1131 notify_func, notify_baton, pool); 1132} 1133 1134svn_error_t * 1135svn_wc_revert(const char *path, 1136 svn_wc_adm_access_t *parent_access, 1137 svn_boolean_t recursive, 1138 svn_boolean_t use_commit_times, 1139 svn_cancel_func_t cancel_func, 1140 void *cancel_baton, 1141 svn_wc_notify_func_t notify_func, 1142 void *notify_baton, 1143 apr_pool_t *pool) 1144{ 1145 struct compat_notify_baton_t nb; 1146 1147 nb.func = notify_func; 1148 nb.baton = notify_baton; 1149 1150 return svn_wc_revert2(path, parent_access, recursive, use_commit_times, 1151 cancel_func, cancel_baton, 1152 compat_call_notify_func, &nb, pool); 1153} 1154 1155svn_error_t * 1156svn_wc_remove_from_revision_control(svn_wc_adm_access_t *adm_access, 1157 const char *name, 1158 svn_boolean_t destroy_wf, 1159 svn_boolean_t instant_error, 1160 svn_cancel_func_t cancel_func, 1161 void *cancel_baton, 1162 apr_pool_t *pool) 1163{ 1164 svn_wc_context_t *wc_ctx; 1165 svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access); 1166 const char *local_abspath = svn_dirent_join( 1167 svn_wc__adm_access_abspath(adm_access), 1168 name, 1169 pool); 1170 1171 /* name must be an entry in adm_access, fail if not */ 1172 SVN_ERR_ASSERT(strcmp(svn_dirent_basename(name, NULL), name) == 0); 1173 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 1174 1175 SVN_ERR(svn_wc_remove_from_revision_control2(wc_ctx, 1176 local_abspath, 1177 destroy_wf, 1178 instant_error, 1179 cancel_func, cancel_baton, 1180 pool)); 1181 1182 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1183} 1184 1185svn_error_t * 1186svn_wc_resolved_conflict4(const char *path, 1187 svn_wc_adm_access_t *adm_access, 1188 svn_boolean_t resolve_text, 1189 svn_boolean_t resolve_props, 1190 svn_boolean_t resolve_tree, 1191 svn_depth_t depth, 1192 svn_wc_conflict_choice_t conflict_choice, 1193 svn_wc_notify_func2_t notify_func, 1194 void *notify_baton, 1195 svn_cancel_func_t cancel_func, 1196 void *cancel_baton, 1197 apr_pool_t *pool) 1198{ 1199 svn_wc_context_t *wc_ctx; 1200 svn_wc__db_t *wc_db = svn_wc__adm_get_db(adm_access); 1201 const char *local_abspath; 1202 1203 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 1204 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 1205 1206 SVN_ERR(svn_wc_resolved_conflict5(wc_ctx, 1207 local_abspath, 1208 depth, 1209 resolve_text, 1210 resolve_props ? "" : NULL, 1211 resolve_tree, 1212 conflict_choice, 1213 cancel_func, 1214 cancel_baton, 1215 notify_func, 1216 notify_baton, 1217 pool)); 1218 1219 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1220 1221} 1222 1223svn_error_t * 1224svn_wc_resolved_conflict(const char *path, 1225 svn_wc_adm_access_t *adm_access, 1226 svn_boolean_t resolve_text, 1227 svn_boolean_t resolve_props, 1228 svn_boolean_t recurse, 1229 svn_wc_notify_func_t notify_func, 1230 void *notify_baton, 1231 apr_pool_t *pool) 1232{ 1233 struct compat_notify_baton_t nb; 1234 1235 nb.func = notify_func; 1236 nb.baton = notify_baton; 1237 1238 return svn_wc_resolved_conflict2(path, adm_access, 1239 resolve_text, resolve_props, recurse, 1240 compat_call_notify_func, &nb, 1241 NULL, NULL, pool); 1242 1243} 1244 1245svn_error_t * 1246svn_wc_resolved_conflict2(const char *path, 1247 svn_wc_adm_access_t *adm_access, 1248 svn_boolean_t resolve_text, 1249 svn_boolean_t resolve_props, 1250 svn_boolean_t recurse, 1251 svn_wc_notify_func2_t notify_func, 1252 void *notify_baton, 1253 svn_cancel_func_t cancel_func, 1254 void *cancel_baton, 1255 apr_pool_t *pool) 1256{ 1257 return svn_wc_resolved_conflict3(path, adm_access, resolve_text, 1258 resolve_props, 1259 SVN_DEPTH_INFINITY_OR_EMPTY(recurse), 1260 svn_wc_conflict_choose_merged, 1261 notify_func, notify_baton, cancel_func, 1262 cancel_baton, pool); 1263} 1264 1265svn_error_t * 1266svn_wc_resolved_conflict3(const char *path, 1267 svn_wc_adm_access_t *adm_access, 1268 svn_boolean_t resolve_text, 1269 svn_boolean_t resolve_props, 1270 svn_depth_t depth, 1271 svn_wc_conflict_choice_t conflict_choice, 1272 svn_wc_notify_func2_t notify_func, 1273 void *notify_baton, 1274 svn_cancel_func_t cancel_func, 1275 void *cancel_baton, 1276 apr_pool_t *pool) 1277{ 1278 return svn_wc_resolved_conflict4(path, adm_access, resolve_text, 1279 resolve_props, FALSE, depth, 1280 svn_wc_conflict_choose_merged, 1281 notify_func, notify_baton, cancel_func, 1282 cancel_baton, pool); 1283} 1284 1285svn_error_t * 1286svn_wc_add_lock(const char *path, 1287 const svn_lock_t *lock, 1288 svn_wc_adm_access_t *adm_access, 1289 apr_pool_t *pool) 1290{ 1291 const char *local_abspath; 1292 svn_wc_context_t *wc_ctx; 1293 1294 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 1295 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 1296 svn_wc__adm_get_db(adm_access), 1297 pool)); 1298 1299 SVN_ERR(svn_wc_add_lock2(wc_ctx, local_abspath, lock, pool)); 1300 1301 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1302} 1303 1304svn_error_t * 1305svn_wc_remove_lock(const char *path, 1306 svn_wc_adm_access_t *adm_access, 1307 apr_pool_t *pool) 1308{ 1309 const char *local_abspath; 1310 svn_wc_context_t *wc_ctx; 1311 1312 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 1313 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 1314 svn_wc__adm_get_db(adm_access), 1315 pool)); 1316 1317 SVN_ERR(svn_wc_remove_lock2(wc_ctx, local_abspath, pool)); 1318 1319 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1320 1321} 1322 1323svn_error_t * 1324svn_wc_get_ancestry(char **url, 1325 svn_revnum_t *rev, 1326 const char *path, 1327 svn_wc_adm_access_t *adm_access, 1328 apr_pool_t *pool) 1329{ 1330 const char *local_abspath; 1331 const svn_wc_entry_t *entry; 1332 1333 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 1334 1335 SVN_ERR(svn_wc__get_entry(&entry, svn_wc__adm_get_db(adm_access), 1336 local_abspath, FALSE, 1337 svn_node_unknown, 1338 pool, pool)); 1339 1340 if (url) 1341 *url = apr_pstrdup(pool, entry->url); 1342 1343 if (rev) 1344 *rev = entry->revision; 1345 1346 return SVN_NO_ERROR; 1347} 1348 1349svn_error_t * 1350svn_wc_set_changelist(const char *path, 1351 const char *changelist, 1352 svn_wc_adm_access_t *adm_access, 1353 svn_cancel_func_t cancel_func, 1354 void *cancel_baton, 1355 svn_wc_notify_func2_t notify_func, 1356 void *notify_baton, 1357 apr_pool_t *pool) 1358{ 1359 const char *local_abspath; 1360 svn_wc_context_t *wc_ctx; 1361 1362 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 1363 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 1364 svn_wc__adm_get_db(adm_access), 1365 pool)); 1366 1367 SVN_ERR(svn_wc_set_changelist2(wc_ctx, local_abspath, changelist, 1368 svn_depth_empty, NULL, 1369 cancel_func, cancel_baton, notify_func, 1370 notify_baton, pool)); 1371 1372 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 1373} 1374 1375 1376/*** From diff.c ***/ 1377/* Used to wrap svn_wc_diff_callbacks_t. */ 1378struct diff_callbacks_wrapper_baton { 1379 const svn_wc_diff_callbacks_t *callbacks; 1380 void *baton; 1381}; 1382 1383/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */ 1384static svn_error_t * 1385wrap_3to1_file_changed(svn_wc_adm_access_t *adm_access, 1386 svn_wc_notify_state_t *contentstate, 1387 svn_wc_notify_state_t *propstate, 1388 svn_boolean_t *tree_conflicted, 1389 const char *path, 1390 const char *tmpfile1, 1391 const char *tmpfile2, 1392 svn_revnum_t rev1, 1393 svn_revnum_t rev2, 1394 const char *mimetype1, 1395 const char *mimetype2, 1396 const apr_array_header_t *propchanges, 1397 apr_hash_t *originalprops, 1398 void *diff_baton) 1399{ 1400 struct diff_callbacks_wrapper_baton *b = diff_baton; 1401 1402 if (tree_conflicted) 1403 *tree_conflicted = FALSE; 1404 1405 if (tmpfile2 != NULL) 1406 SVN_ERR(b->callbacks->file_changed(adm_access, contentstate, path, 1407 tmpfile1, tmpfile2, 1408 rev1, rev2, mimetype1, mimetype2, 1409 b->baton)); 1410 if (propchanges->nelts > 0) 1411 SVN_ERR(b->callbacks->props_changed(adm_access, propstate, path, 1412 propchanges, originalprops, 1413 b->baton)); 1414 1415 return SVN_NO_ERROR; 1416} 1417 1418/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */ 1419static svn_error_t * 1420wrap_3to1_file_added(svn_wc_adm_access_t *adm_access, 1421 svn_wc_notify_state_t *contentstate, 1422 svn_wc_notify_state_t *propstate, 1423 svn_boolean_t *tree_conflicted, 1424 const char *path, 1425 const char *tmpfile1, 1426 const char *tmpfile2, 1427 svn_revnum_t rev1, 1428 svn_revnum_t rev2, 1429 const char *mimetype1, 1430 const char *mimetype2, 1431 const apr_array_header_t *propchanges, 1432 apr_hash_t *originalprops, 1433 void *diff_baton) 1434{ 1435 struct diff_callbacks_wrapper_baton *b = diff_baton; 1436 1437 if (tree_conflicted) 1438 *tree_conflicted = FALSE; 1439 1440 SVN_ERR(b->callbacks->file_added(adm_access, contentstate, path, 1441 tmpfile1, tmpfile2, rev1, rev2, 1442 mimetype1, mimetype2, b->baton)); 1443 if (propchanges->nelts > 0) 1444 SVN_ERR(b->callbacks->props_changed(adm_access, propstate, path, 1445 propchanges, originalprops, 1446 b->baton)); 1447 1448 return SVN_NO_ERROR; 1449} 1450 1451/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */ 1452static svn_error_t * 1453wrap_3to1_file_deleted(svn_wc_adm_access_t *adm_access, 1454 svn_wc_notify_state_t *state, 1455 svn_boolean_t *tree_conflicted, 1456 const char *path, 1457 const char *tmpfile1, 1458 const char *tmpfile2, 1459 const char *mimetype1, 1460 const char *mimetype2, 1461 apr_hash_t *originalprops, 1462 void *diff_baton) 1463{ 1464 struct diff_callbacks_wrapper_baton *b = diff_baton; 1465 1466 if (tree_conflicted) 1467 *tree_conflicted = FALSE; 1468 1469 SVN_ERR_ASSERT(originalprops); 1470 1471 return b->callbacks->file_deleted(adm_access, state, path, 1472 tmpfile1, tmpfile2, mimetype1, mimetype2, 1473 b->baton); 1474} 1475 1476/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */ 1477static svn_error_t * 1478wrap_3to1_dir_added(svn_wc_adm_access_t *adm_access, 1479 svn_wc_notify_state_t *state, 1480 svn_boolean_t *tree_conflicted, 1481 const char *path, 1482 svn_revnum_t rev, 1483 void *diff_baton) 1484{ 1485 struct diff_callbacks_wrapper_baton *b = diff_baton; 1486 1487 if (tree_conflicted) 1488 *tree_conflicted = FALSE; 1489 1490 return b->callbacks->dir_added(adm_access, state, path, rev, b->baton); 1491} 1492 1493/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */ 1494static svn_error_t * 1495wrap_3to1_dir_deleted(svn_wc_adm_access_t *adm_access, 1496 svn_wc_notify_state_t *state, 1497 svn_boolean_t *tree_conflicted, 1498 const char *path, 1499 void *diff_baton) 1500{ 1501 struct diff_callbacks_wrapper_baton *b = diff_baton; 1502 1503 if (tree_conflicted) 1504 *tree_conflicted = FALSE; 1505 1506 return b->callbacks->dir_deleted(adm_access, state, path, b->baton); 1507} 1508 1509/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t. */ 1510static svn_error_t * 1511wrap_3to1_dir_props_changed(svn_wc_adm_access_t *adm_access, 1512 svn_wc_notify_state_t *state, 1513 svn_boolean_t *tree_conflicted, 1514 const char *path, 1515 const apr_array_header_t *propchanges, 1516 apr_hash_t *originalprops, 1517 void *diff_baton) 1518{ 1519 struct diff_callbacks_wrapper_baton *b = diff_baton; 1520 1521 if (tree_conflicted) 1522 *tree_conflicted = FALSE; 1523 1524 return b->callbacks->props_changed(adm_access, state, path, propchanges, 1525 originalprops, b->baton); 1526} 1527 1528/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t 1529 and svn_wc_diff_callbacks2_t. */ 1530static svn_error_t * 1531wrap_3to1or2_dir_opened(svn_wc_adm_access_t *adm_access, 1532 svn_boolean_t *tree_conflicted, 1533 const char *path, 1534 svn_revnum_t rev, 1535 void *diff_baton) 1536{ 1537 if (tree_conflicted) 1538 *tree_conflicted = FALSE; 1539 /* Do nothing. */ 1540 return SVN_NO_ERROR; 1541} 1542 1543/* An svn_wc_diff_callbacks3_t function for wrapping svn_wc_diff_callbacks_t 1544 and svn_wc_diff_callbacks2_t. */ 1545static svn_error_t * 1546wrap_3to1or2_dir_closed(svn_wc_adm_access_t *adm_access, 1547 svn_wc_notify_state_t *propstate, 1548 svn_wc_notify_state_t *contentstate, 1549 svn_boolean_t *tree_conflicted, 1550 const char *path, 1551 void *diff_baton) 1552{ 1553 if (contentstate) 1554 *contentstate = svn_wc_notify_state_unknown; 1555 if (propstate) 1556 *propstate = svn_wc_notify_state_unknown; 1557 if (tree_conflicted) 1558 *tree_conflicted = FALSE; 1559 /* Do nothing. */ 1560 return SVN_NO_ERROR; 1561} 1562 1563/* Used to wrap svn_diff_callbacks_t as an svn_wc_diff_callbacks3_t. */ 1564static struct svn_wc_diff_callbacks3_t diff_callbacks_wrapper = { 1565 wrap_3to1_file_changed, 1566 wrap_3to1_file_added, 1567 wrap_3to1_file_deleted, 1568 wrap_3to1_dir_added, 1569 wrap_3to1_dir_deleted, 1570 wrap_3to1_dir_props_changed, 1571 wrap_3to1or2_dir_opened, 1572 wrap_3to1or2_dir_closed 1573}; 1574 1575 1576 1577/* Used to wrap svn_wc_diff_callbacks2_t. */ 1578struct diff_callbacks2_wrapper_baton { 1579 const svn_wc_diff_callbacks2_t *callbacks2; 1580 void *baton; 1581}; 1582 1583/* An svn_wc_diff_callbacks3_t function for wrapping 1584 * svn_wc_diff_callbacks2_t. */ 1585static svn_error_t * 1586wrap_3to2_file_changed(svn_wc_adm_access_t *adm_access, 1587 svn_wc_notify_state_t *contentstate, 1588 svn_wc_notify_state_t *propstate, 1589 svn_boolean_t *tree_conflicted, 1590 const char *path, 1591 const char *tmpfile1, 1592 const char *tmpfile2, 1593 svn_revnum_t rev1, 1594 svn_revnum_t rev2, 1595 const char *mimetype1, 1596 const char *mimetype2, 1597 const apr_array_header_t *propchanges, 1598 apr_hash_t *originalprops, 1599 void *diff_baton) 1600{ 1601 struct diff_callbacks2_wrapper_baton *b = diff_baton; 1602 1603 if (tree_conflicted) 1604 *tree_conflicted = FALSE; 1605 1606 return b->callbacks2->file_changed(adm_access, contentstate, propstate, 1607 path, tmpfile1, tmpfile2, 1608 rev1, rev2, mimetype1, mimetype2, 1609 propchanges, originalprops, b->baton); 1610} 1611 1612/* An svn_wc_diff_callbacks3_t function for wrapping 1613 * svn_wc_diff_callbacks2_t. */ 1614static svn_error_t * 1615wrap_3to2_file_added(svn_wc_adm_access_t *adm_access, 1616 svn_wc_notify_state_t *contentstate, 1617 svn_wc_notify_state_t *propstate, 1618 svn_boolean_t *tree_conflicted, 1619 const char *path, 1620 const char *tmpfile1, 1621 const char *tmpfile2, 1622 svn_revnum_t rev1, 1623 svn_revnum_t rev2, 1624 const char *mimetype1, 1625 const char *mimetype2, 1626 const apr_array_header_t *propchanges, 1627 apr_hash_t *originalprops, 1628 void *diff_baton) 1629{ 1630 struct diff_callbacks2_wrapper_baton *b = diff_baton; 1631 1632 if (tree_conflicted) 1633 *tree_conflicted = FALSE; 1634 1635 return b->callbacks2->file_added(adm_access, contentstate, propstate, path, 1636 tmpfile1, tmpfile2, rev1, rev2, 1637 mimetype1, mimetype2, propchanges, 1638 originalprops, b->baton); 1639} 1640 1641/* An svn_wc_diff_callbacks3_t function for wrapping 1642 * svn_wc_diff_callbacks2_t. */ 1643static svn_error_t * 1644wrap_3to2_file_deleted(svn_wc_adm_access_t *adm_access, 1645 svn_wc_notify_state_t *state, 1646 svn_boolean_t *tree_conflicted, 1647 const char *path, 1648 const char *tmpfile1, 1649 const char *tmpfile2, 1650 const char *mimetype1, 1651 const char *mimetype2, 1652 apr_hash_t *originalprops, 1653 void *diff_baton) 1654{ 1655 struct diff_callbacks2_wrapper_baton *b = diff_baton; 1656 1657 if (tree_conflicted) 1658 *tree_conflicted = FALSE; 1659 1660 return b->callbacks2->file_deleted(adm_access, state, path, 1661 tmpfile1, tmpfile2, mimetype1, mimetype2, 1662 originalprops, b->baton); 1663} 1664 1665/* An svn_wc_diff_callbacks3_t function for wrapping 1666 * svn_wc_diff_callbacks2_t. */ 1667static svn_error_t * 1668wrap_3to2_dir_added(svn_wc_adm_access_t *adm_access, 1669 svn_wc_notify_state_t *state, 1670 svn_boolean_t *tree_conflicted, 1671 const char *path, 1672 svn_revnum_t rev, 1673 void *diff_baton) 1674{ 1675 struct diff_callbacks2_wrapper_baton *b = diff_baton; 1676 1677 if (tree_conflicted) 1678 *tree_conflicted = FALSE; 1679 1680 return b->callbacks2->dir_added(adm_access, state, path, rev, b->baton); 1681} 1682 1683/* An svn_wc_diff_callbacks3_t function for wrapping 1684 * svn_wc_diff_callbacks2_t. */ 1685static svn_error_t * 1686wrap_3to2_dir_deleted(svn_wc_adm_access_t *adm_access, 1687 svn_wc_notify_state_t *state, 1688 svn_boolean_t *tree_conflicted, 1689 const char *path, 1690 void *diff_baton) 1691{ 1692 struct diff_callbacks2_wrapper_baton *b = diff_baton; 1693 1694 if (tree_conflicted) 1695 *tree_conflicted = FALSE; 1696 1697 return b->callbacks2->dir_deleted(adm_access, state, path, b->baton); 1698} 1699 1700/* An svn_wc_diff_callbacks3_t function for wrapping 1701 * svn_wc_diff_callbacks2_t. */ 1702static svn_error_t * 1703wrap_3to2_dir_props_changed(svn_wc_adm_access_t *adm_access, 1704 svn_wc_notify_state_t *state, 1705 svn_boolean_t *tree_conflicted, 1706 const char *path, 1707 const apr_array_header_t *propchanges, 1708 apr_hash_t *originalprops, 1709 void *diff_baton) 1710{ 1711 struct diff_callbacks2_wrapper_baton *b = diff_baton; 1712 1713 if (tree_conflicted) 1714 *tree_conflicted = FALSE; 1715 1716 return b->callbacks2->dir_props_changed(adm_access, state, path, propchanges, 1717 originalprops, b->baton); 1718} 1719 1720/* Used to wrap svn_diff_callbacks2_t as an svn_wc_diff_callbacks3_t. */ 1721static struct svn_wc_diff_callbacks3_t diff_callbacks2_wrapper = { 1722 wrap_3to2_file_changed, 1723 wrap_3to2_file_added, 1724 wrap_3to2_file_deleted, 1725 wrap_3to2_dir_added, 1726 wrap_3to2_dir_deleted, 1727 wrap_3to2_dir_props_changed, 1728 wrap_3to1or2_dir_opened, 1729 wrap_3to1or2_dir_closed 1730}; 1731 1732 1733 1734/* Used to wrap svn_wc_diff_callbacks3_t. */ 1735struct diff_callbacks3_wrapper_baton { 1736 const svn_wc_diff_callbacks3_t *callbacks3; 1737 svn_wc__db_t *db; 1738 void *baton; 1739 const char *anchor; 1740 const char *anchor_abspath; 1741}; 1742 1743static svn_error_t * 1744wrap_4to3_file_opened(svn_boolean_t *tree_conflicted, 1745 svn_boolean_t *skip, 1746 const char *path, 1747 svn_revnum_t rev, 1748 void *diff_baton, 1749 apr_pool_t *scratch_pool) 1750{ 1751 return SVN_NO_ERROR; 1752} 1753 1754/* An svn_wc_diff_callbacks4_t function for wrapping 1755 * svn_wc_diff_callbacks3_t. */ 1756static svn_error_t * 1757wrap_4to3_file_changed(svn_wc_notify_state_t *contentstate, 1758 svn_wc_notify_state_t *propstate, 1759 svn_boolean_t *tree_conflicted, 1760 const char *path, 1761 const char *tmpfile1, 1762 const char *tmpfile2, 1763 svn_revnum_t rev1, 1764 svn_revnum_t rev2, 1765 const char *mimetype1, 1766 const char *mimetype2, 1767 const apr_array_header_t *propchanges, 1768 apr_hash_t *originalprops, 1769 void *diff_baton, 1770 apr_pool_t *scratch_pool) 1771{ 1772 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1773 svn_wc_adm_access_t *adm_access; 1774 const char *dir = svn_relpath_dirname(path, scratch_pool); 1775 1776 adm_access = svn_wc__adm_retrieve_internal2( 1777 b->db, 1778 svn_dirent_join(b->anchor_abspath, dir, scratch_pool), 1779 scratch_pool); 1780 1781 return b->callbacks3->file_changed(adm_access, contentstate, propstate, 1782 tree_conflicted, 1783 svn_dirent_join(b->anchor, path, 1784 scratch_pool), 1785 tmpfile1, tmpfile2, 1786 rev1, rev2, mimetype1, mimetype2, 1787 propchanges, originalprops, b->baton); 1788} 1789 1790/* An svn_wc_diff_callbacks4_t function for wrapping 1791 * svn_wc_diff_callbacks3_t. */ 1792static svn_error_t * 1793wrap_4to3_file_added(svn_wc_notify_state_t *contentstate, 1794 svn_wc_notify_state_t *propstate, 1795 svn_boolean_t *tree_conflicted, 1796 const char *path, 1797 const char *tmpfile1, 1798 const char *tmpfile2, 1799 svn_revnum_t rev1, 1800 svn_revnum_t rev2, 1801 const char *mimetype1, 1802 const char *mimetype2, 1803 const char *copyfrom_path, 1804 svn_revnum_t copyfrom_revision, 1805 const apr_array_header_t *propchanges, 1806 apr_hash_t *originalprops, 1807 void *diff_baton, 1808 apr_pool_t *scratch_pool) 1809{ 1810 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1811 svn_wc_adm_access_t *adm_access; 1812 const char *dir = svn_relpath_dirname(path, scratch_pool); 1813 1814 adm_access = svn_wc__adm_retrieve_internal2( 1815 b->db, 1816 svn_dirent_join(b->anchor_abspath, dir, scratch_pool), 1817 scratch_pool); 1818 1819 return b->callbacks3->file_added(adm_access, contentstate, propstate, 1820 tree_conflicted, 1821 svn_dirent_join(b->anchor, path, 1822 scratch_pool), 1823 tmpfile1, tmpfile2, 1824 rev1, rev2, mimetype1, mimetype2, 1825 propchanges, originalprops, b->baton); 1826} 1827 1828/* An svn_wc_diff_callbacks4_t function for wrapping 1829 * svn_wc_diff_callbacks3_t. */ 1830static svn_error_t * 1831wrap_4to3_file_deleted(svn_wc_notify_state_t *state, 1832 svn_boolean_t *tree_conflicted, 1833 const char *path, 1834 const char *tmpfile1, 1835 const char *tmpfile2, 1836 const char *mimetype1, 1837 const char *mimetype2, 1838 apr_hash_t *originalprops, 1839 void *diff_baton, 1840 apr_pool_t *scratch_pool) 1841{ 1842 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1843 svn_wc_adm_access_t *adm_access; 1844 const char *dir = svn_relpath_dirname(path, scratch_pool); 1845 1846 adm_access = svn_wc__adm_retrieve_internal2( 1847 b->db, 1848 svn_dirent_join(b->anchor_abspath, dir, scratch_pool), 1849 scratch_pool); 1850 1851 return b->callbacks3->file_deleted(adm_access, state, tree_conflicted, 1852 svn_dirent_join(b->anchor, path, 1853 scratch_pool), 1854 tmpfile1, tmpfile2, 1855 mimetype1, mimetype2, originalprops, 1856 b->baton); 1857} 1858 1859/* An svn_wc_diff_callbacks4_t function for wrapping 1860 * svn_wc_diff_callbacks3_t. */ 1861static svn_error_t * 1862wrap_4to3_dir_added(svn_wc_notify_state_t *state, 1863 svn_boolean_t *tree_conflicted, 1864 svn_boolean_t *skip, 1865 svn_boolean_t *skip_children, 1866 const char *path, 1867 svn_revnum_t rev, 1868 const char *copyfrom_path, 1869 svn_revnum_t copyfrom_revision, 1870 void *diff_baton, 1871 apr_pool_t *scratch_pool) 1872{ 1873 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1874 svn_wc_adm_access_t *adm_access; 1875 1876 adm_access = svn_wc__adm_retrieve_internal2( 1877 b->db, 1878 svn_dirent_join(b->anchor_abspath, path, scratch_pool), 1879 scratch_pool); 1880 1881 return b->callbacks3->dir_added(adm_access, state, tree_conflicted, 1882 svn_dirent_join(b->anchor, path, 1883 scratch_pool), 1884 rev, b->baton); 1885} 1886 1887/* An svn_wc_diff_callbacks4_t function for wrapping 1888 * svn_wc_diff_callbacks3_t. */ 1889static svn_error_t * 1890wrap_4to3_dir_deleted(svn_wc_notify_state_t *state, 1891 svn_boolean_t *tree_conflicted, 1892 const char *path, 1893 void *diff_baton, 1894 apr_pool_t *scratch_pool) 1895{ 1896 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1897 svn_wc_adm_access_t *adm_access; 1898 1899 adm_access = svn_wc__adm_retrieve_internal2( 1900 b->db, 1901 svn_dirent_join(b->anchor_abspath, path, scratch_pool), 1902 scratch_pool); 1903 1904 return b->callbacks3->dir_deleted(adm_access, state, tree_conflicted, 1905 svn_dirent_join(b->anchor, path, 1906 scratch_pool), 1907 b->baton); 1908} 1909 1910/* An svn_wc_diff_callbacks4_t function for wrapping 1911 * svn_wc_diff_callbacks3_t. */ 1912static svn_error_t * 1913wrap_4to3_dir_props_changed(svn_wc_notify_state_t *propstate, 1914 svn_boolean_t *tree_conflicted, 1915 const char *path, 1916 svn_boolean_t dir_was_added, 1917 const apr_array_header_t *propchanges, 1918 apr_hash_t *original_props, 1919 void *diff_baton, 1920 apr_pool_t *scratch_pool) 1921{ 1922 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1923 svn_wc_adm_access_t *adm_access; 1924 1925 adm_access = svn_wc__adm_retrieve_internal2( 1926 b->db, 1927 svn_dirent_join(b->anchor_abspath, path, scratch_pool), 1928 scratch_pool); 1929 1930 return b->callbacks3->dir_props_changed(adm_access, propstate, 1931 tree_conflicted, 1932 svn_dirent_join(b->anchor, path, 1933 scratch_pool), 1934 propchanges, original_props, 1935 b->baton); 1936} 1937 1938/* An svn_wc_diff_callbacks4_t function for wrapping 1939 * svn_wc_diff_callbacks3_t. */ 1940static svn_error_t * 1941wrap_4to3_dir_opened(svn_boolean_t *tree_conflicted, 1942 svn_boolean_t *skip, 1943 svn_boolean_t *skip_children, 1944 const char *path, 1945 svn_revnum_t rev, 1946 void *diff_baton, 1947 apr_pool_t *scratch_pool) 1948{ 1949 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1950 svn_wc_adm_access_t *adm_access; 1951 1952 adm_access = svn_wc__adm_retrieve_internal2( 1953 b->db, 1954 svn_dirent_join(b->anchor_abspath, path, scratch_pool), 1955 scratch_pool); 1956 if (skip_children) 1957 *skip_children = FALSE; 1958 1959 return b->callbacks3->dir_opened(adm_access, tree_conflicted, 1960 svn_dirent_join(b->anchor, path, 1961 scratch_pool), 1962 rev, b->baton); 1963} 1964 1965/* An svn_wc_diff_callbacks4_t function for wrapping 1966 * svn_wc_diff_callbacks3_t. */ 1967static svn_error_t * 1968wrap_4to3_dir_closed(svn_wc_notify_state_t *contentstate, 1969 svn_wc_notify_state_t *propstate, 1970 svn_boolean_t *tree_conflicted, 1971 const char *path, 1972 svn_boolean_t dir_was_added, 1973 void *diff_baton, 1974 apr_pool_t *scratch_pool) 1975{ 1976 struct diff_callbacks3_wrapper_baton *b = diff_baton; 1977 svn_wc_adm_access_t *adm_access; 1978 1979 adm_access = svn_wc__adm_retrieve_internal2( 1980 b->db, 1981 svn_dirent_join(b->anchor_abspath, path, scratch_pool), 1982 scratch_pool); 1983 1984 return b->callbacks3->dir_closed(adm_access, contentstate, propstate, 1985 tree_conflicted, 1986 svn_dirent_join(b->anchor, path, 1987 scratch_pool), 1988 b->baton); 1989} 1990 1991 1992/* Used to wrap svn_diff_callbacks3_t as an svn_wc_diff_callbacks4_t. */ 1993static struct svn_wc_diff_callbacks4_t diff_callbacks3_wrapper = { 1994 wrap_4to3_file_opened, 1995 wrap_4to3_file_changed, 1996 wrap_4to3_file_added, 1997 wrap_4to3_file_deleted, 1998 wrap_4to3_dir_deleted, 1999 wrap_4to3_dir_opened, 2000 wrap_4to3_dir_added, 2001 wrap_4to3_dir_props_changed, 2002 wrap_4to3_dir_closed 2003}; 2004 2005 2006svn_error_t * 2007svn_wc_get_diff_editor6(const svn_delta_editor_t **editor, 2008 void **edit_baton, 2009 svn_wc_context_t *wc_ctx, 2010 const char *anchor_abspath, 2011 const char *target, 2012 svn_depth_t depth, 2013 svn_boolean_t ignore_ancestry, 2014 svn_boolean_t show_copies_as_adds, 2015 svn_boolean_t use_git_diff_format, 2016 svn_boolean_t use_text_base, 2017 svn_boolean_t reverse_order, 2018 svn_boolean_t server_performs_filtering, 2019 const apr_array_header_t *changelist_filter, 2020 const svn_wc_diff_callbacks4_t *callbacks, 2021 void *callback_baton, 2022 svn_cancel_func_t cancel_func, 2023 void *cancel_baton, 2024 apr_pool_t *result_pool, 2025 apr_pool_t *scratch_pool) 2026{ 2027 const svn_diff_tree_processor_t *diff_processor; 2028 2029 /* --git implies --show-copies-as-adds */ 2030 if (use_git_diff_format) 2031 show_copies_as_adds = TRUE; 2032 2033 /* --show-copies-as-adds implies --notice-ancestry */ 2034 if (show_copies_as_adds) 2035 ignore_ancestry = FALSE; 2036 2037 SVN_ERR(svn_wc__wrap_diff_callbacks(&diff_processor, 2038 callbacks, callback_baton, TRUE, 2039 result_pool, scratch_pool)); 2040 2041 if (reverse_order) 2042 diff_processor = svn_diff__tree_processor_reverse_create( 2043 diff_processor, NULL, result_pool); 2044 2045 if (! show_copies_as_adds) 2046 diff_processor = svn_diff__tree_processor_copy_as_changed_create( 2047 diff_processor, result_pool); 2048 2049 return svn_error_trace( 2050 svn_wc__get_diff_editor(editor, edit_baton, 2051 wc_ctx, 2052 anchor_abspath, target, 2053 depth, 2054 ignore_ancestry, use_text_base, 2055 reverse_order, server_performs_filtering, 2056 changelist_filter, 2057 diff_processor, 2058 cancel_func, cancel_baton, 2059 result_pool, scratch_pool)); 2060} 2061 2062 2063svn_error_t * 2064svn_wc_get_diff_editor5(svn_wc_adm_access_t *anchor, 2065 const char *target, 2066 const svn_wc_diff_callbacks3_t *callbacks, 2067 void *callback_baton, 2068 svn_depth_t depth, 2069 svn_boolean_t ignore_ancestry, 2070 svn_boolean_t use_text_base, 2071 svn_boolean_t reverse_order, 2072 svn_cancel_func_t cancel_func, 2073 void *cancel_baton, 2074 const apr_array_header_t *changelist_filter, 2075 const svn_delta_editor_t **editor, 2076 void **edit_baton, 2077 apr_pool_t *pool) 2078{ 2079 struct diff_callbacks3_wrapper_baton *b = apr_palloc(pool, sizeof(*b)); 2080 svn_wc_context_t *wc_ctx; 2081 svn_wc__db_t *db = svn_wc__adm_get_db(anchor); 2082 2083 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 2084 2085 b->callbacks3 = callbacks; 2086 b->baton = callback_baton; 2087 b->db = db; 2088 b->anchor = svn_wc_adm_access_path(anchor); 2089 b->anchor_abspath = svn_wc__adm_access_abspath(anchor); 2090 2091 SVN_ERR(svn_wc_get_diff_editor6(editor, 2092 edit_baton, 2093 wc_ctx, 2094 b->anchor_abspath, 2095 target, 2096 depth, 2097 ignore_ancestry, 2098 FALSE, 2099 FALSE, 2100 use_text_base, 2101 reverse_order, 2102 FALSE, 2103 changelist_filter, 2104 &diff_callbacks3_wrapper, 2105 b, 2106 cancel_func, 2107 cancel_baton, 2108 pool, 2109 pool)); 2110 2111 /* Can't destroy wc_ctx. It is used by the diff editor */ 2112 2113 return SVN_NO_ERROR; 2114} 2115 2116svn_error_t * 2117svn_wc_get_diff_editor4(svn_wc_adm_access_t *anchor, 2118 const char *target, 2119 const svn_wc_diff_callbacks2_t *callbacks, 2120 void *callback_baton, 2121 svn_depth_t depth, 2122 svn_boolean_t ignore_ancestry, 2123 svn_boolean_t use_text_base, 2124 svn_boolean_t reverse_order, 2125 svn_cancel_func_t cancel_func, 2126 void *cancel_baton, 2127 const apr_array_header_t *changelist_filter, 2128 const svn_delta_editor_t **editor, 2129 void **edit_baton, 2130 apr_pool_t *pool) 2131{ 2132 struct diff_callbacks2_wrapper_baton *b = apr_palloc(pool, sizeof(*b)); 2133 b->callbacks2 = callbacks; 2134 b->baton = callback_baton; 2135 return svn_wc_get_diff_editor5(anchor, 2136 target, 2137 &diff_callbacks2_wrapper, 2138 b, 2139 depth, 2140 ignore_ancestry, 2141 use_text_base, 2142 reverse_order, 2143 cancel_func, 2144 cancel_baton, 2145 changelist_filter, 2146 editor, 2147 edit_baton, 2148 pool); 2149} 2150 2151svn_error_t * 2152svn_wc_get_diff_editor3(svn_wc_adm_access_t *anchor, 2153 const char *target, 2154 const svn_wc_diff_callbacks2_t *callbacks, 2155 void *callback_baton, 2156 svn_boolean_t recurse, 2157 svn_boolean_t ignore_ancestry, 2158 svn_boolean_t use_text_base, 2159 svn_boolean_t reverse_order, 2160 svn_cancel_func_t cancel_func, 2161 void *cancel_baton, 2162 const svn_delta_editor_t **editor, 2163 void **edit_baton, 2164 apr_pool_t *pool) 2165{ 2166 return svn_wc_get_diff_editor4(anchor, 2167 target, 2168 callbacks, 2169 callback_baton, 2170 SVN_DEPTH_INFINITY_OR_FILES(recurse), 2171 ignore_ancestry, 2172 use_text_base, 2173 reverse_order, 2174 cancel_func, 2175 cancel_baton, 2176 NULL, 2177 editor, 2178 edit_baton, 2179 pool); 2180} 2181 2182svn_error_t * 2183svn_wc_get_diff_editor2(svn_wc_adm_access_t *anchor, 2184 const char *target, 2185 const svn_wc_diff_callbacks_t *callbacks, 2186 void *callback_baton, 2187 svn_boolean_t recurse, 2188 svn_boolean_t ignore_ancestry, 2189 svn_boolean_t use_text_base, 2190 svn_boolean_t reverse_order, 2191 svn_cancel_func_t cancel_func, 2192 void *cancel_baton, 2193 const svn_delta_editor_t **editor, 2194 void **edit_baton, 2195 apr_pool_t *pool) 2196{ 2197 struct diff_callbacks_wrapper_baton *b = apr_palloc(pool, sizeof(*b)); 2198 b->callbacks = callbacks; 2199 b->baton = callback_baton; 2200 return svn_wc_get_diff_editor5(anchor, target, &diff_callbacks_wrapper, b, 2201 SVN_DEPTH_INFINITY_OR_FILES(recurse), 2202 ignore_ancestry, use_text_base, 2203 reverse_order, cancel_func, cancel_baton, 2204 NULL, editor, edit_baton, pool); 2205} 2206 2207svn_error_t * 2208svn_wc_get_diff_editor(svn_wc_adm_access_t *anchor, 2209 const char *target, 2210 const svn_wc_diff_callbacks_t *callbacks, 2211 void *callback_baton, 2212 svn_boolean_t recurse, 2213 svn_boolean_t use_text_base, 2214 svn_boolean_t reverse_order, 2215 svn_cancel_func_t cancel_func, 2216 void *cancel_baton, 2217 const svn_delta_editor_t **editor, 2218 void **edit_baton, 2219 apr_pool_t *pool) 2220{ 2221 return svn_wc_get_diff_editor2(anchor, target, callbacks, callback_baton, 2222 recurse, FALSE, use_text_base, reverse_order, 2223 cancel_func, cancel_baton, 2224 editor, edit_baton, pool); 2225} 2226 2227svn_error_t * 2228svn_wc_diff5(svn_wc_adm_access_t *anchor, 2229 const char *target, 2230 const svn_wc_diff_callbacks3_t *callbacks, 2231 void *callback_baton, 2232 svn_depth_t depth, 2233 svn_boolean_t ignore_ancestry, 2234 const apr_array_header_t *changelist_filter, 2235 apr_pool_t *pool) 2236{ 2237 struct diff_callbacks3_wrapper_baton *b = apr_palloc(pool, sizeof(*b)); 2238 svn_wc_context_t *wc_ctx; 2239 svn_wc__db_t *db = svn_wc__adm_get_db(anchor); 2240 2241 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 2242 2243 b->callbacks3 = callbacks; 2244 b->baton = callback_baton; 2245 b->anchor = svn_wc_adm_access_path(anchor); 2246 b->anchor_abspath = svn_wc__adm_access_abspath(anchor); 2247 2248 SVN_ERR(svn_wc_diff6(wc_ctx, 2249 svn_dirent_join(b->anchor_abspath, target, pool), 2250 &diff_callbacks3_wrapper, 2251 b, 2252 depth, 2253 ignore_ancestry, 2254 FALSE, 2255 FALSE, 2256 changelist_filter, 2257 NULL, NULL, 2258 pool)); 2259 2260 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 2261} 2262 2263svn_error_t * 2264svn_wc_diff4(svn_wc_adm_access_t *anchor, 2265 const char *target, 2266 const svn_wc_diff_callbacks2_t *callbacks, 2267 void *callback_baton, 2268 svn_depth_t depth, 2269 svn_boolean_t ignore_ancestry, 2270 const apr_array_header_t *changelist_filter, 2271 apr_pool_t *pool) 2272{ 2273 struct diff_callbacks2_wrapper_baton *b = apr_palloc(pool, sizeof(*b)); 2274 b->callbacks2 = callbacks; 2275 b->baton = callback_baton; 2276 2277 return svn_wc_diff5(anchor, target, &diff_callbacks2_wrapper, b, 2278 depth, ignore_ancestry, changelist_filter, pool); 2279} 2280 2281svn_error_t * 2282svn_wc_diff3(svn_wc_adm_access_t *anchor, 2283 const char *target, 2284 const svn_wc_diff_callbacks2_t *callbacks, 2285 void *callback_baton, 2286 svn_boolean_t recurse, 2287 svn_boolean_t ignore_ancestry, 2288 apr_pool_t *pool) 2289{ 2290 return svn_wc_diff4(anchor, target, callbacks, callback_baton, 2291 SVN_DEPTH_INFINITY_OR_FILES(recurse), ignore_ancestry, 2292 NULL, pool); 2293} 2294 2295svn_error_t * 2296svn_wc_diff2(svn_wc_adm_access_t *anchor, 2297 const char *target, 2298 const svn_wc_diff_callbacks_t *callbacks, 2299 void *callback_baton, 2300 svn_boolean_t recurse, 2301 svn_boolean_t ignore_ancestry, 2302 apr_pool_t *pool) 2303{ 2304 struct diff_callbacks_wrapper_baton *b = apr_pcalloc(pool, sizeof(*b)); 2305 b->callbacks = callbacks; 2306 b->baton = callback_baton; 2307 return svn_wc_diff5(anchor, target, &diff_callbacks_wrapper, b, 2308 SVN_DEPTH_INFINITY_OR_FILES(recurse), ignore_ancestry, 2309 NULL, pool); 2310} 2311 2312svn_error_t * 2313svn_wc_diff(svn_wc_adm_access_t *anchor, 2314 const char *target, 2315 const svn_wc_diff_callbacks_t *callbacks, 2316 void *callback_baton, 2317 svn_boolean_t recurse, 2318 apr_pool_t *pool) 2319{ 2320 return svn_wc_diff2(anchor, target, callbacks, callback_baton, 2321 recurse, FALSE, pool); 2322} 2323 2324/*** From entries.c ***/ 2325svn_error_t * 2326svn_wc_walk_entries2(const char *path, 2327 svn_wc_adm_access_t *adm_access, 2328 const svn_wc_entry_callbacks_t *walk_callbacks, 2329 void *walk_baton, 2330 svn_boolean_t show_hidden, 2331 svn_cancel_func_t cancel_func, 2332 void *cancel_baton, 2333 apr_pool_t *pool) 2334{ 2335 svn_wc_entry_callbacks2_t walk_cb2 = { 0 }; 2336 walk_cb2.found_entry = walk_callbacks->found_entry; 2337 walk_cb2.handle_error = svn_wc__walker_default_error_handler; 2338 return svn_wc_walk_entries3(path, adm_access, 2339 &walk_cb2, walk_baton, svn_depth_infinity, 2340 show_hidden, cancel_func, cancel_baton, pool); 2341} 2342 2343svn_error_t * 2344svn_wc_walk_entries(const char *path, 2345 svn_wc_adm_access_t *adm_access, 2346 const svn_wc_entry_callbacks_t *walk_callbacks, 2347 void *walk_baton, 2348 svn_boolean_t show_hidden, 2349 apr_pool_t *pool) 2350{ 2351 return svn_wc_walk_entries2(path, adm_access, walk_callbacks, 2352 walk_baton, show_hidden, NULL, NULL, 2353 pool); 2354} 2355 2356svn_error_t * 2357svn_wc_mark_missing_deleted(const char *path, 2358 svn_wc_adm_access_t *parent, 2359 apr_pool_t *pool) 2360{ 2361 /* With a single DB a node will never be missing */ 2362 return svn_error_createf(SVN_ERR_WC_PATH_FOUND, NULL, 2363 _("Unexpectedly found '%s': " 2364 "path is marked 'missing'"), 2365 svn_dirent_local_style(path, pool)); 2366} 2367 2368 2369/*** From props.c ***/ 2370svn_error_t * 2371svn_wc_parse_externals_description2(apr_array_header_t **externals_p, 2372 const char *parent_directory, 2373 const char *desc, 2374 apr_pool_t *pool) 2375{ 2376 apr_array_header_t *list; 2377 apr_pool_t *subpool = svn_pool_create(pool); 2378 2379 SVN_ERR(svn_wc_parse_externals_description3(externals_p ? &list : NULL, 2380 parent_directory, desc, 2381 TRUE, subpool)); 2382 2383 if (externals_p) 2384 { 2385 int i; 2386 2387 *externals_p = apr_array_make(pool, list->nelts, 2388 sizeof(svn_wc_external_item_t *)); 2389 for (i = 0; i < list->nelts; i++) 2390 { 2391 svn_wc_external_item2_t *item2 = APR_ARRAY_IDX(list, i, 2392 svn_wc_external_item2_t *); 2393 svn_wc_external_item_t *item = apr_palloc(pool, sizeof (*item)); 2394 2395 if (item2->target_dir) 2396 item->target_dir = apr_pstrdup(pool, item2->target_dir); 2397 if (item2->url) 2398 item->url = apr_pstrdup(pool, item2->url); 2399 item->revision = item2->revision; 2400 2401 APR_ARRAY_PUSH(*externals_p, svn_wc_external_item_t *) = item; 2402 } 2403 } 2404 2405 svn_pool_destroy(subpool); 2406 2407 return SVN_NO_ERROR; 2408} 2409 2410 2411svn_error_t * 2412svn_wc_parse_externals_description(apr_hash_t **externals_p, 2413 const char *parent_directory, 2414 const char *desc, 2415 apr_pool_t *pool) 2416{ 2417 apr_array_header_t *list; 2418 2419 SVN_ERR(svn_wc_parse_externals_description2(externals_p ? &list : NULL, 2420 parent_directory, desc, pool)); 2421 2422 /* Store all of the items into the hash if that was requested. */ 2423 if (externals_p) 2424 { 2425 int i; 2426 2427 *externals_p = apr_hash_make(pool); 2428 for (i = 0; i < list->nelts; i++) 2429 { 2430 svn_wc_external_item_t *item; 2431 item = APR_ARRAY_IDX(list, i, svn_wc_external_item_t *); 2432 2433 svn_hash_sets(*externals_p, item->target_dir, item); 2434 } 2435 } 2436 return SVN_NO_ERROR; 2437} 2438 2439svn_error_t * 2440svn_wc_prop_set3(const char *name, 2441 const svn_string_t *value, 2442 const char *path, 2443 svn_wc_adm_access_t *adm_access, 2444 svn_boolean_t skip_checks, 2445 svn_wc_notify_func2_t notify_func, 2446 void *notify_baton, 2447 apr_pool_t *pool) 2448{ 2449 svn_wc_context_t *wc_ctx; 2450 const char *local_abspath; 2451 svn_error_t *err; 2452 2453 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 2454 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 2455 svn_wc__adm_get_db(adm_access), 2456 pool)); 2457 2458 err = svn_wc_prop_set4(wc_ctx, local_abspath, 2459 name, value, 2460 svn_depth_empty, 2461 skip_checks, NULL /* changelist_filter */, 2462 NULL, NULL /* cancellation */, 2463 notify_func, notify_baton, 2464 pool); 2465 2466 if (err && err->apr_err == SVN_ERR_WC_INVALID_SCHEDULE) 2467 svn_error_clear(err); 2468 else 2469 SVN_ERR(err); 2470 2471 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 2472} 2473 2474svn_error_t * 2475svn_wc_prop_set2(const char *name, 2476 const svn_string_t *value, 2477 const char *path, 2478 svn_wc_adm_access_t *adm_access, 2479 svn_boolean_t skip_checks, 2480 apr_pool_t *pool) 2481{ 2482 return svn_wc_prop_set3(name, value, path, adm_access, skip_checks, 2483 NULL, NULL, pool); 2484} 2485 2486svn_error_t * 2487svn_wc_prop_set(const char *name, 2488 const svn_string_t *value, 2489 const char *path, 2490 svn_wc_adm_access_t *adm_access, 2491 apr_pool_t *pool) 2492{ 2493 return svn_wc_prop_set2(name, value, path, adm_access, FALSE, pool); 2494} 2495 2496svn_error_t * 2497svn_wc_prop_list(apr_hash_t **props, 2498 const char *path, 2499 svn_wc_adm_access_t *adm_access, 2500 apr_pool_t *pool) 2501{ 2502 svn_wc_context_t *wc_ctx; 2503 const char *local_abspath; 2504 svn_error_t *err; 2505 2506 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 2507 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 2508 svn_wc__adm_get_db(adm_access), pool)); 2509 2510 err = svn_wc_prop_list2(props, wc_ctx, local_abspath, pool, pool); 2511 if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) 2512 { 2513 *props = apr_hash_make(pool); 2514 svn_error_clear(err); 2515 err = NULL; 2516 } 2517 2518 return svn_error_compose_create(err, svn_wc_context_destroy(wc_ctx)); 2519} 2520 2521svn_error_t * 2522svn_wc_prop_get(const svn_string_t **value, 2523 const char *name, 2524 const char *path, 2525 svn_wc_adm_access_t *adm_access, 2526 apr_pool_t *pool) 2527{ 2528 2529 svn_wc_context_t *wc_ctx; 2530 const char *local_abspath; 2531 svn_error_t *err; 2532 2533 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 2534 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 2535 svn_wc__adm_get_db(adm_access), pool)); 2536 2537 err = svn_wc_prop_get2(value, wc_ctx, local_abspath, name, pool, pool); 2538 2539 if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) 2540 { 2541 *value = NULL; 2542 svn_error_clear(err); 2543 err = NULL; 2544 } 2545 2546 return svn_error_compose_create(err, svn_wc_context_destroy(wc_ctx)); 2547} 2548 2549/* baton for conflict_func_1to2_wrapper */ 2550struct conflict_func_1to2_baton 2551{ 2552 svn_wc_conflict_resolver_func_t inner_func; 2553 void *inner_baton; 2554}; 2555 2556 2557/* Implements svn_wc_conflict_resolver_func2_t */ 2558static svn_error_t * 2559conflict_func_1to2_wrapper(svn_wc_conflict_result_t **result, 2560 const svn_wc_conflict_description2_t *conflict, 2561 void *baton, 2562 apr_pool_t *result_pool, 2563 apr_pool_t *scratch_pool) 2564{ 2565 struct conflict_func_1to2_baton *btn = baton; 2566 svn_wc_conflict_description_t *cd = svn_wc__cd2_to_cd(conflict, 2567 scratch_pool); 2568 2569 return svn_error_trace(btn->inner_func(result, cd, btn->inner_baton, 2570 result_pool)); 2571} 2572 2573svn_error_t * 2574svn_wc_merge_props2(svn_wc_notify_state_t *state, 2575 const char *path, 2576 svn_wc_adm_access_t *adm_access, 2577 apr_hash_t *baseprops, 2578 const apr_array_header_t *propchanges, 2579 svn_boolean_t base_merge, 2580 svn_boolean_t dry_run, 2581 svn_wc_conflict_resolver_func_t conflict_func, 2582 void *conflict_baton, 2583 apr_pool_t *scratch_pool) 2584{ 2585 const char *local_abspath; 2586 svn_error_t *err; 2587 svn_wc_context_t *wc_ctx; 2588 struct conflict_func_1to2_baton conflict_wrapper; 2589 2590 if (base_merge && !dry_run) 2591 return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, 2592 U_("base_merge=TRUE is no longer supported; " 2593 "see notes/api-errata/1.7/wc006.txt")); 2594 2595 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool)); 2596 2597 conflict_wrapper.inner_func = conflict_func; 2598 conflict_wrapper.inner_baton = conflict_baton; 2599 2600 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, 2601 svn_wc__adm_get_db(adm_access), 2602 scratch_pool)); 2603 2604 err = svn_wc_merge_props3(state, 2605 wc_ctx, 2606 local_abspath, 2607 NULL /* left_version */, 2608 NULL /* right_version */, 2609 baseprops, 2610 propchanges, 2611 dry_run, 2612 conflict_func ? conflict_func_1to2_wrapper 2613 : NULL, 2614 &conflict_wrapper, 2615 NULL, NULL, 2616 scratch_pool); 2617 2618 if (err) 2619 switch(err->apr_err) 2620 { 2621 case SVN_ERR_WC_PATH_NOT_FOUND: 2622 case SVN_ERR_WC_PATH_UNEXPECTED_STATUS: 2623 err->apr_err = SVN_ERR_UNVERSIONED_RESOURCE; 2624 break; 2625 } 2626 return svn_error_trace( 2627 svn_error_compose_create(err, 2628 svn_wc_context_destroy(wc_ctx))); 2629} 2630 2631svn_error_t * 2632svn_wc_merge_props(svn_wc_notify_state_t *state, 2633 const char *path, 2634 svn_wc_adm_access_t *adm_access, 2635 apr_hash_t *baseprops, 2636 const apr_array_header_t *propchanges, 2637 svn_boolean_t base_merge, 2638 svn_boolean_t dry_run, 2639 apr_pool_t *pool) 2640{ 2641 return svn_wc_merge_props2(state, path, adm_access, baseprops, propchanges, 2642 base_merge, dry_run, NULL, NULL, pool); 2643} 2644 2645 2646svn_error_t * 2647svn_wc_merge_prop_diffs(svn_wc_notify_state_t *state, 2648 const char *path, 2649 svn_wc_adm_access_t *adm_access, 2650 const apr_array_header_t *propchanges, 2651 svn_boolean_t base_merge, 2652 svn_boolean_t dry_run, 2653 apr_pool_t *pool) 2654{ 2655 /* NOTE: Here, we use implementation knowledge. The public 2656 svn_wc_merge_props2 doesn't allow NULL as baseprops argument, but we know 2657 that it works. */ 2658 return svn_wc_merge_props2(state, path, adm_access, NULL, propchanges, 2659 base_merge, dry_run, NULL, NULL, pool); 2660} 2661 2662svn_error_t * 2663svn_wc_get_prop_diffs(apr_array_header_t **propchanges, 2664 apr_hash_t **original_props, 2665 const char *path, 2666 svn_wc_adm_access_t *adm_access, 2667 apr_pool_t *pool) 2668{ 2669 svn_wc_context_t *wc_ctx; 2670 const char *local_abspath; 2671 2672 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 2673 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 2674 svn_wc__adm_get_db(adm_access), pool)); 2675 2676 SVN_ERR(svn_wc_get_prop_diffs2(propchanges, original_props, wc_ctx, 2677 local_abspath, pool, pool)); 2678 2679 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 2680} 2681 2682 2683svn_error_t * 2684svn_wc_props_modified_p(svn_boolean_t *modified_p, 2685 const char *path, 2686 svn_wc_adm_access_t *adm_access, 2687 apr_pool_t *pool) 2688{ 2689 svn_wc_context_t *wc_ctx; 2690 const char *local_abspath; 2691 svn_error_t *err; 2692 2693 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 2694 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 2695 svn_wc__adm_get_db(adm_access), pool)); 2696 2697 err = svn_wc_props_modified_p2(modified_p, 2698 wc_ctx, 2699 local_abspath, 2700 pool); 2701 2702 if (err) 2703 { 2704 if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) 2705 return svn_error_trace(err); 2706 2707 svn_error_clear(err); 2708 *modified_p = FALSE; 2709 } 2710 2711 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 2712} 2713 2714 2715svn_error_t * 2716svn_wc__status2_from_3(svn_wc_status2_t **status, 2717 const svn_wc_status3_t *old_status, 2718 svn_wc_context_t *wc_ctx, 2719 const char *local_abspath, 2720 apr_pool_t *result_pool, 2721 apr_pool_t *scratch_pool) 2722{ 2723 const svn_wc_entry_t *entry = NULL; 2724 2725 if (old_status == NULL) 2726 { 2727 *status = NULL; 2728 return SVN_NO_ERROR; 2729 } 2730 2731 *status = apr_pcalloc(result_pool, sizeof(**status)); 2732 2733 if (old_status->versioned) 2734 { 2735 svn_error_t *err; 2736 err= svn_wc__get_entry(&entry, wc_ctx->db, local_abspath, FALSE, 2737 svn_node_unknown, result_pool, scratch_pool); 2738 2739 if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND) 2740 svn_error_clear(err); 2741 else 2742 SVN_ERR(err); 2743 } 2744 2745 (*status)->entry = entry; 2746 (*status)->copied = old_status->copied; 2747 (*status)->repos_lock = svn_lock_dup(old_status->repos_lock, result_pool); 2748 2749 if (old_status->repos_relpath) 2750 (*status)->url = svn_path_url_add_component2(old_status->repos_root_url, 2751 old_status->repos_relpath, 2752 result_pool); 2753 (*status)->ood_last_cmt_rev = old_status->ood_changed_rev; 2754 (*status)->ood_last_cmt_date = old_status->ood_changed_date; 2755 (*status)->ood_kind = old_status->ood_kind; 2756 (*status)->ood_last_cmt_author = old_status->ood_changed_author; 2757 2758 if (old_status->conflicted) 2759 { 2760 const svn_wc_conflict_description2_t *tree_conflict2; 2761 SVN_ERR(svn_wc__get_tree_conflict(&tree_conflict2, wc_ctx, local_abspath, 2762 scratch_pool, scratch_pool)); 2763 (*status)->tree_conflict = svn_wc__cd2_to_cd(tree_conflict2, result_pool); 2764 } 2765 2766 (*status)->switched = old_status->switched; 2767 2768 (*status)->text_status = old_status->node_status; 2769 (*status)->prop_status = old_status->prop_status; 2770 2771 (*status)->repos_text_status = old_status->repos_node_status; 2772 (*status)->repos_prop_status = old_status->repos_prop_status; 2773 2774 /* Some values might be inherited from properties */ 2775 if (old_status->node_status == svn_wc_status_modified 2776 || old_status->node_status == svn_wc_status_conflicted) 2777 (*status)->text_status = old_status->text_status; 2778 2779 /* (Currently a no-op, but just make sure it is ok) */ 2780 if (old_status->repos_node_status == svn_wc_status_modified 2781 || old_status->repos_node_status == svn_wc_status_conflicted) 2782 (*status)->repos_text_status = old_status->repos_text_status; 2783 2784 if (old_status->node_status == svn_wc_status_added) 2785 (*status)->prop_status = svn_wc_status_none; /* No separate info */ 2786 2787 /* Find pristine_text_status value */ 2788 switch (old_status->text_status) 2789 { 2790 case svn_wc_status_none: 2791 case svn_wc_status_normal: 2792 case svn_wc_status_modified: 2793 (*status)->pristine_text_status = old_status->text_status; 2794 break; 2795 case svn_wc_status_conflicted: 2796 default: 2797 /* ### Fetch compare data, or fall back to the documented 2798 not retrieved behavior? */ 2799 (*status)->pristine_text_status = svn_wc_status_none; 2800 break; 2801 } 2802 2803 /* Find pristine_prop_status value */ 2804 switch (old_status->prop_status) 2805 { 2806 case svn_wc_status_none: 2807 case svn_wc_status_normal: 2808 case svn_wc_status_modified: 2809 if (old_status->node_status != svn_wc_status_added 2810 && old_status->node_status != svn_wc_status_deleted 2811 && old_status->node_status != svn_wc_status_replaced) 2812 { 2813 (*status)->pristine_prop_status = old_status->prop_status; 2814 } 2815 else 2816 (*status)->pristine_prop_status = svn_wc_status_none; 2817 break; 2818 case svn_wc_status_conflicted: 2819 default: 2820 /* ### Fetch compare data, or fall back to the documented 2821 not retrieved behavior? */ 2822 (*status)->pristine_prop_status = svn_wc_status_none; 2823 break; 2824 } 2825 2826 if (old_status->versioned 2827 && old_status->conflicted 2828 && old_status->node_status != svn_wc_status_obstructed 2829 && (old_status->kind == svn_node_file 2830 || old_status->node_status != svn_wc_status_missing)) 2831 { 2832 svn_boolean_t text_conflict_p, prop_conflict_p; 2833 2834 /* The entry says there was a conflict, but the user might have 2835 marked it as resolved by deleting the artifact files, so check 2836 for that. */ 2837 SVN_ERR(svn_wc__internal_conflicted_p(&text_conflict_p, 2838 &prop_conflict_p, 2839 NULL, 2840 wc_ctx->db, local_abspath, 2841 scratch_pool)); 2842 2843 if (text_conflict_p) 2844 (*status)->text_status = svn_wc_status_conflicted; 2845 2846 if (prop_conflict_p) 2847 (*status)->prop_status = svn_wc_status_conflicted; 2848 } 2849 2850 return SVN_NO_ERROR; 2851} 2852 2853 2854 2855/*** From status.c ***/ 2856 2857struct status4_wrapper_baton 2858{ 2859 svn_wc_status_func3_t old_func; 2860 void *old_baton; 2861 const char *anchor_abspath; 2862 const char *anchor_relpath; 2863 svn_wc_context_t *wc_ctx; 2864}; 2865 2866/* */ 2867static svn_error_t * 2868status4_wrapper_func(void *baton, 2869 const char *local_abspath, 2870 const svn_wc_status3_t *status, 2871 apr_pool_t *scratch_pool) 2872{ 2873 struct status4_wrapper_baton *swb = baton; 2874 svn_wc_status2_t *dup; 2875 const char *path = local_abspath; 2876 2877 SVN_ERR(svn_wc__status2_from_3(&dup, status, swb->wc_ctx, local_abspath, 2878 scratch_pool, scratch_pool)); 2879 2880 if (swb->anchor_abspath != NULL) 2881 { 2882 path = svn_dirent_join( 2883 swb->anchor_relpath, 2884 svn_dirent_skip_ancestor(swb->anchor_abspath, local_abspath), 2885 scratch_pool); 2886 } 2887 2888 return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool); 2889} 2890 2891 2892svn_error_t * 2893svn_wc_get_status_editor5(const svn_delta_editor_t **editor, 2894 void **edit_baton, 2895 void **set_locks_baton, 2896 svn_revnum_t *edit_revision, 2897 svn_wc_context_t *wc_ctx, 2898 const char *anchor_abspath, 2899 const char *target_basename, 2900 svn_depth_t depth, 2901 svn_boolean_t get_all, 2902 svn_boolean_t no_ignore, 2903 svn_boolean_t depth_as_sticky, 2904 svn_boolean_t server_performs_filtering, 2905 const apr_array_header_t *ignore_patterns, 2906 svn_wc_status_func4_t status_func, 2907 void *status_baton, 2908 svn_cancel_func_t cancel_func, 2909 void *cancel_baton, 2910 apr_pool_t *result_pool, 2911 apr_pool_t *scratch_pool) 2912{ 2913 return svn_error_trace( 2914 svn_wc__get_status_editor(editor, edit_baton, 2915 set_locks_baton, 2916 edit_revision, 2917 wc_ctx, 2918 anchor_abspath, 2919 target_basename, 2920 depth, get_all, 2921 TRUE, /* check_working_copy */ 2922 no_ignore, depth_as_sticky, 2923 server_performs_filtering, 2924 ignore_patterns, 2925 status_func, status_baton, 2926 cancel_func, cancel_baton, 2927 result_pool, 2928 scratch_pool)); 2929} 2930 2931 2932svn_error_t * 2933svn_wc_get_status_editor4(const svn_delta_editor_t **editor, 2934 void **edit_baton, 2935 void **set_locks_baton, 2936 svn_revnum_t *edit_revision, 2937 svn_wc_adm_access_t *anchor, 2938 const char *target, 2939 svn_depth_t depth, 2940 svn_boolean_t get_all, 2941 svn_boolean_t no_ignore, 2942 const apr_array_header_t *ignore_patterns, 2943 svn_wc_status_func3_t status_func, 2944 void *status_baton, 2945 svn_cancel_func_t cancel_func, 2946 void *cancel_baton, 2947 svn_wc_traversal_info_t *traversal_info, 2948 apr_pool_t *pool) 2949{ 2950 struct status4_wrapper_baton *swb = apr_palloc(pool, sizeof(*swb)); 2951 svn_wc__db_t *wc_db; 2952 svn_wc_context_t *wc_ctx; 2953 const char *anchor_abspath; 2954 2955 swb->old_func = status_func; 2956 swb->old_baton = status_baton; 2957 2958 wc_db = svn_wc__adm_get_db(anchor); 2959 2960 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 2961 wc_db, pool)); 2962 2963 swb->wc_ctx = wc_ctx; 2964 2965 anchor_abspath = svn_wc__adm_access_abspath(anchor); 2966 2967 if (!svn_dirent_is_absolute(svn_wc_adm_access_path(anchor))) 2968 { 2969 swb->anchor_abspath = anchor_abspath; 2970 swb->anchor_relpath = svn_wc_adm_access_path(anchor); 2971 } 2972 else 2973 { 2974 swb->anchor_abspath = NULL; 2975 swb->anchor_relpath = NULL; 2976 } 2977 2978 /* Before subversion 1.7 status always handled depth as sticky. 1.7 made 2979 the output of svn status by default match the result of what would be 2980 updated by a similar svn update. (Following the documentation) */ 2981 2982 SVN_ERR(svn_wc_get_status_editor5(editor, edit_baton, set_locks_baton, 2983 edit_revision, wc_ctx, anchor_abspath, 2984 target, depth, get_all, 2985 no_ignore, 2986 (depth != svn_depth_unknown) /*as_sticky*/, 2987 FALSE /* server_performs_filtering */, 2988 ignore_patterns, 2989 status4_wrapper_func, swb, 2990 cancel_func, cancel_baton, 2991 pool, pool)); 2992 2993 if (traversal_info) 2994 { 2995 const char *local_path = svn_wc_adm_access_path(anchor); 2996 const char *local_abspath = anchor_abspath; 2997 if (*target) 2998 { 2999 local_path = svn_dirent_join(local_path, target, pool); 3000 local_abspath = svn_dirent_join(local_abspath, target, pool); 3001 } 3002 3003 SVN_ERR(gather_traversal_info(wc_ctx, local_abspath, local_path, depth, 3004 traversal_info, TRUE, TRUE, 3005 pool)); 3006 } 3007 3008 /* We can't destroy wc_ctx here, because the editor needs it while it's 3009 driven. */ 3010 return SVN_NO_ERROR; 3011} 3012 3013struct status_editor3_compat_baton 3014{ 3015 svn_wc_status_func2_t old_func; 3016 void *old_baton; 3017}; 3018 3019/* */ 3020static svn_error_t * 3021status_editor3_compat_func(void *baton, 3022 const char *path, 3023 svn_wc_status2_t *status, 3024 apr_pool_t *pool) 3025{ 3026 struct status_editor3_compat_baton *secb = baton; 3027 3028 secb->old_func(secb->old_baton, path, status); 3029 return SVN_NO_ERROR; 3030} 3031 3032svn_error_t * 3033svn_wc_get_status_editor3(const svn_delta_editor_t **editor, 3034 void **edit_baton, 3035 void **set_locks_baton, 3036 svn_revnum_t *edit_revision, 3037 svn_wc_adm_access_t *anchor, 3038 const char *target, 3039 svn_depth_t depth, 3040 svn_boolean_t get_all, 3041 svn_boolean_t no_ignore, 3042 const apr_array_header_t *ignore_patterns, 3043 svn_wc_status_func2_t status_func, 3044 void *status_baton, 3045 svn_cancel_func_t cancel_func, 3046 void *cancel_baton, 3047 svn_wc_traversal_info_t *traversal_info, 3048 apr_pool_t *pool) 3049{ 3050 /* This baton must live beyond this function. Alloc on heap. */ 3051 struct status_editor3_compat_baton *secb = apr_palloc(pool, sizeof(*secb)); 3052 3053 secb->old_func = status_func; 3054 secb->old_baton = status_baton; 3055 3056 return svn_wc_get_status_editor4(editor, edit_baton, set_locks_baton, 3057 edit_revision, anchor, target, depth, 3058 get_all, no_ignore, ignore_patterns, 3059 status_editor3_compat_func, secb, 3060 cancel_func, cancel_baton, traversal_info, 3061 pool); 3062} 3063 3064svn_error_t * 3065svn_wc_get_status_editor2(const svn_delta_editor_t **editor, 3066 void **edit_baton, 3067 void **set_locks_baton, 3068 svn_revnum_t *edit_revision, 3069 svn_wc_adm_access_t *anchor, 3070 const char *target, 3071 apr_hash_t *config, 3072 svn_boolean_t recurse, 3073 svn_boolean_t get_all, 3074 svn_boolean_t no_ignore, 3075 svn_wc_status_func2_t status_func, 3076 void *status_baton, 3077 svn_cancel_func_t cancel_func, 3078 void *cancel_baton, 3079 svn_wc_traversal_info_t *traversal_info, 3080 apr_pool_t *pool) 3081{ 3082 apr_array_header_t *ignores; 3083 3084 SVN_ERR(svn_wc_get_default_ignores(&ignores, config, pool)); 3085 return svn_wc_get_status_editor3(editor, 3086 edit_baton, 3087 set_locks_baton, 3088 edit_revision, 3089 anchor, 3090 target, 3091 SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse), 3092 get_all, 3093 no_ignore, 3094 ignores, 3095 status_func, 3096 status_baton, 3097 cancel_func, 3098 cancel_baton, 3099 traversal_info, 3100 pool); 3101} 3102 3103 3104/* Helpers for deprecated svn_wc_status_editor(), of type 3105 svn_wc_status_func2_t. */ 3106struct old_status_func_cb_baton 3107{ 3108 svn_wc_status_func_t original_func; 3109 void *original_baton; 3110}; 3111 3112/* */ 3113static void old_status_func_cb(void *baton, 3114 const char *path, 3115 svn_wc_status2_t *status) 3116{ 3117 struct old_status_func_cb_baton *b = baton; 3118 svn_wc_status_t *stat = (svn_wc_status_t *) status; 3119 3120 b->original_func(b->original_baton, path, stat); 3121} 3122 3123svn_error_t * 3124svn_wc_get_status_editor(const svn_delta_editor_t **editor, 3125 void **edit_baton, 3126 svn_revnum_t *edit_revision, 3127 svn_wc_adm_access_t *anchor, 3128 const char *target, 3129 apr_hash_t *config, 3130 svn_boolean_t recurse, 3131 svn_boolean_t get_all, 3132 svn_boolean_t no_ignore, 3133 svn_wc_status_func_t status_func, 3134 void *status_baton, 3135 svn_cancel_func_t cancel_func, 3136 void *cancel_baton, 3137 svn_wc_traversal_info_t *traversal_info, 3138 apr_pool_t *pool) 3139{ 3140 struct old_status_func_cb_baton *b = apr_pcalloc(pool, sizeof(*b)); 3141 apr_array_header_t *ignores; 3142 b->original_func = status_func; 3143 b->original_baton = status_baton; 3144 SVN_ERR(svn_wc_get_default_ignores(&ignores, config, pool)); 3145 return svn_wc_get_status_editor3(editor, edit_baton, NULL, edit_revision, 3146 anchor, target, 3147 SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse), 3148 get_all, no_ignore, ignores, 3149 old_status_func_cb, b, 3150 cancel_func, cancel_baton, 3151 traversal_info, pool); 3152} 3153 3154svn_error_t * 3155svn_wc_status(svn_wc_status_t **status, 3156 const char *path, 3157 svn_wc_adm_access_t *adm_access, 3158 apr_pool_t *pool) 3159{ 3160 svn_wc_status2_t *stat2; 3161 3162 SVN_ERR(svn_wc_status2(&stat2, path, adm_access, pool)); 3163 *status = (svn_wc_status_t *) stat2; 3164 return SVN_NO_ERROR; 3165} 3166 3167 3168static svn_wc_conflict_description_t * 3169conflict_description_dup(const svn_wc_conflict_description_t *conflict, 3170 apr_pool_t *pool) 3171{ 3172 svn_wc_conflict_description_t *new_conflict; 3173 3174 new_conflict = apr_pcalloc(pool, sizeof(*new_conflict)); 3175 3176 /* Shallow copy all members. */ 3177 *new_conflict = *conflict; 3178 3179 if (conflict->path) 3180 new_conflict->path = apr_pstrdup(pool, conflict->path); 3181 if (conflict->property_name) 3182 new_conflict->property_name = apr_pstrdup(pool, conflict->property_name); 3183 if (conflict->mime_type) 3184 new_conflict->mime_type = apr_pstrdup(pool, conflict->mime_type); 3185 /* NOTE: We cannot make a deep copy of adm_access. */ 3186 if (conflict->base_file) 3187 new_conflict->base_file = apr_pstrdup(pool, conflict->base_file); 3188 if (conflict->their_file) 3189 new_conflict->their_file = apr_pstrdup(pool, conflict->their_file); 3190 if (conflict->my_file) 3191 new_conflict->my_file = apr_pstrdup(pool, conflict->my_file); 3192 if (conflict->merged_file) 3193 new_conflict->merged_file = apr_pstrdup(pool, conflict->merged_file); 3194 if (conflict->src_left_version) 3195 new_conflict->src_left_version = 3196 svn_wc_conflict_version_dup(conflict->src_left_version, pool); 3197 if (conflict->src_right_version) 3198 new_conflict->src_right_version = 3199 svn_wc_conflict_version_dup(conflict->src_right_version, pool); 3200 3201 return new_conflict; 3202} 3203 3204 3205svn_wc_status2_t * 3206svn_wc_dup_status2(const svn_wc_status2_t *orig_stat, 3207 apr_pool_t *pool) 3208{ 3209 svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat)); 3210 3211 /* Shallow copy all members. */ 3212 *new_stat = *orig_stat; 3213 3214 /* Now go back and dup the deep items into this pool. */ 3215 if (orig_stat->entry) 3216 new_stat->entry = svn_wc_entry_dup(orig_stat->entry, pool); 3217 3218 if (orig_stat->repos_lock) 3219 new_stat->repos_lock = svn_lock_dup(orig_stat->repos_lock, pool); 3220 3221 if (orig_stat->url) 3222 new_stat->url = apr_pstrdup(pool, orig_stat->url); 3223 3224 if (orig_stat->ood_last_cmt_author) 3225 new_stat->ood_last_cmt_author 3226 = apr_pstrdup(pool, orig_stat->ood_last_cmt_author); 3227 3228 if (orig_stat->tree_conflict) 3229 new_stat->tree_conflict 3230 = conflict_description_dup(orig_stat->tree_conflict, pool); 3231 3232 /* Return the new hotness. */ 3233 return new_stat; 3234} 3235 3236svn_wc_status_t * 3237svn_wc_dup_status(const svn_wc_status_t *orig_stat, 3238 apr_pool_t *pool) 3239{ 3240 svn_wc_status_t *new_stat = apr_palloc(pool, sizeof(*new_stat)); 3241 3242 /* Shallow copy all members. */ 3243 *new_stat = *orig_stat; 3244 3245 /* Now go back and dup the deep item into this pool. */ 3246 if (orig_stat->entry) 3247 new_stat->entry = svn_wc_entry_dup(orig_stat->entry, pool); 3248 3249 /* Return the new hotness. */ 3250 return new_stat; 3251} 3252 3253svn_error_t * 3254svn_wc_get_ignores(apr_array_header_t **patterns, 3255 apr_hash_t *config, 3256 svn_wc_adm_access_t *adm_access, 3257 apr_pool_t *pool) 3258{ 3259 svn_wc_context_t *wc_ctx; 3260 const char *local_abspath; 3261 3262 SVN_ERR(svn_dirent_get_absolute(&local_abspath, 3263 svn_wc_adm_access_path(adm_access), pool)); 3264 3265 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 3266 svn_wc__adm_get_db(adm_access), 3267 pool)); 3268 3269 SVN_ERR(svn_wc_get_ignores2(patterns, wc_ctx, local_abspath, config, pool, 3270 pool)); 3271 3272 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 3273} 3274 3275svn_error_t * 3276svn_wc_status2(svn_wc_status2_t **status, 3277 const char *path, 3278 svn_wc_adm_access_t *adm_access, 3279 apr_pool_t *pool) 3280{ 3281 const char *local_abspath; 3282 svn_wc_context_t *wc_ctx; 3283 svn_wc_status3_t *stat3; 3284 3285 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 3286 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 3287 svn_wc__adm_get_db(adm_access), 3288 pool)); 3289 3290 SVN_ERR(svn_wc_status3(&stat3, wc_ctx, local_abspath, pool, pool)); 3291 SVN_ERR(svn_wc__status2_from_3(status, stat3, wc_ctx, local_abspath, 3292 pool, pool)); 3293 3294 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 3295} 3296 3297 3298/*** From update_editor.c ***/ 3299 3300svn_error_t * 3301svn_wc_add_repos_file3(const char *dst_path, 3302 svn_wc_adm_access_t *adm_access, 3303 svn_stream_t *new_base_contents, 3304 svn_stream_t *new_contents, 3305 apr_hash_t *new_base_props, 3306 apr_hash_t *new_props, 3307 const char *copyfrom_url, 3308 svn_revnum_t copyfrom_rev, 3309 svn_cancel_func_t cancel_func, 3310 void *cancel_baton, 3311 svn_wc_notify_func2_t notify_func, 3312 void *notify_baton, 3313 apr_pool_t *pool) 3314{ 3315 const char *local_abspath; 3316 svn_wc_context_t *wc_ctx; 3317 3318 SVN_ERR(svn_dirent_get_absolute(&local_abspath, dst_path, pool)); 3319 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 3320 svn_wc__adm_get_db(adm_access), 3321 pool)); 3322 3323 SVN_ERR(svn_wc_add_repos_file4(wc_ctx, 3324 local_abspath, 3325 new_base_contents, 3326 new_contents, 3327 new_base_props, 3328 new_props, 3329 copyfrom_url, 3330 copyfrom_rev, 3331 cancel_func, cancel_baton, 3332 pool)); 3333 3334 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 3335} 3336 3337svn_error_t * 3338svn_wc_add_repos_file2(const char *dst_path, 3339 svn_wc_adm_access_t *adm_access, 3340 const char *new_text_base_path, 3341 const char *new_text_path, 3342 apr_hash_t *new_base_props, 3343 apr_hash_t *new_props, 3344 const char *copyfrom_url, 3345 svn_revnum_t copyfrom_rev, 3346 apr_pool_t *pool) 3347{ 3348 svn_stream_t *new_base_contents; 3349 svn_stream_t *new_contents = NULL; 3350 3351 SVN_ERR(svn_stream_open_readonly(&new_base_contents, new_text_base_path, 3352 pool, pool)); 3353 3354 if (new_text_path) 3355 { 3356 /* NOTE: the specified path may *not* be under version control. 3357 It is most likely sitting in .svn/tmp/. Thus, we cannot use the 3358 typical WC functions to access "special", "keywords" or "EOL" 3359 information. We need to look at the properties given to us. */ 3360 3361 /* If the new file is special, then we can simply open the given 3362 contents since it is already in normal form. */ 3363 if (svn_hash_gets(new_props, SVN_PROP_SPECIAL) != NULL) 3364 { 3365 SVN_ERR(svn_stream_open_readonly(&new_contents, new_text_path, 3366 pool, pool)); 3367 } 3368 else 3369 { 3370 /* The new text contents need to be detrans'd into normal form. */ 3371 svn_subst_eol_style_t eol_style; 3372 const char *eol_str; 3373 apr_hash_t *keywords = NULL; 3374 svn_string_t *list; 3375 3376 list = svn_hash_gets(new_props, SVN_PROP_KEYWORDS); 3377 if (list != NULL) 3378 { 3379 /* Since we are detranslating, all of the keyword values 3380 can be "". */ 3381 SVN_ERR(svn_subst_build_keywords2(&keywords, 3382 list->data, 3383 "", "", 0, "", 3384 pool)); 3385 if (apr_hash_count(keywords) == 0) 3386 keywords = NULL; 3387 } 3388 3389 svn_subst_eol_style_from_value(&eol_style, &eol_str, 3390 svn_hash_gets(new_props, 3391 SVN_PROP_EOL_STYLE)); 3392 3393 if (svn_subst_translation_required(eol_style, eol_str, keywords, 3394 FALSE, FALSE)) 3395 { 3396 SVN_ERR(svn_subst_stream_detranslated(&new_contents, 3397 new_text_path, 3398 eol_style, eol_str, 3399 FALSE, 3400 keywords, 3401 FALSE, 3402 pool)); 3403 } 3404 else 3405 { 3406 SVN_ERR(svn_stream_open_readonly(&new_contents, new_text_path, 3407 pool, pool)); 3408 } 3409 } 3410 } 3411 3412 SVN_ERR(svn_wc_add_repos_file3(dst_path, adm_access, 3413 new_base_contents, new_contents, 3414 new_base_props, new_props, 3415 copyfrom_url, copyfrom_rev, 3416 NULL, NULL, NULL, NULL, 3417 pool)); 3418 3419 /* The API contract states that the text files will be removed upon 3420 successful completion. add_repos_file3() does not remove the files 3421 since it only has streams on them. Toss 'em now. */ 3422 svn_error_clear(svn_io_remove_file(new_text_base_path, pool)); 3423 if (new_text_path) 3424 svn_error_clear(svn_io_remove_file(new_text_path, pool)); 3425 3426 return SVN_NO_ERROR; 3427} 3428 3429 3430svn_error_t * 3431svn_wc_add_repos_file(const char *dst_path, 3432 svn_wc_adm_access_t *adm_access, 3433 const char *new_text_path, 3434 apr_hash_t *new_props, 3435 const char *copyfrom_url, 3436 svn_revnum_t copyfrom_rev, 3437 apr_pool_t *pool) 3438{ 3439 return svn_wc_add_repos_file2(dst_path, adm_access, 3440 new_text_path, NULL, 3441 new_props, NULL, 3442 copyfrom_url, copyfrom_rev, 3443 pool); 3444} 3445 3446svn_error_t * 3447svn_wc_get_actual_target(const char *path, 3448 const char **anchor, 3449 const char **target, 3450 apr_pool_t *pool) 3451{ 3452 svn_wc_context_t *wc_ctx; 3453 3454 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool)); 3455 SVN_ERR(svn_wc_get_actual_target2(anchor, target, wc_ctx, path, pool, pool)); 3456 3457 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 3458} 3459 3460/* This function has no internal variant as its behavior on switched 3461 non-directories is not what you would expect. But this happens to 3462 be the legacy behavior of this function. */ 3463svn_error_t * 3464svn_wc_is_wc_root2(svn_boolean_t *wc_root, 3465 svn_wc_context_t *wc_ctx, 3466 const char *local_abspath, 3467 apr_pool_t *scratch_pool) 3468{ 3469 svn_boolean_t is_root; 3470 svn_boolean_t is_switched; 3471 svn_node_kind_t kind; 3472 svn_error_t *err; 3473 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); 3474 3475 err = svn_wc__db_is_switched(&is_root, &is_switched, &kind, 3476 wc_ctx->db, local_abspath, scratch_pool); 3477 3478 if (err) 3479 { 3480 if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND && 3481 err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY) 3482 return svn_error_trace(err); 3483 3484 return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, err, err->message); 3485 } 3486 3487 *wc_root = is_root || (kind == svn_node_dir && is_switched); 3488 3489 return SVN_NO_ERROR; 3490} 3491 3492svn_error_t * 3493svn_wc_is_wc_root(svn_boolean_t *wc_root, 3494 const char *path, 3495 svn_wc_adm_access_t *adm_access, 3496 apr_pool_t *pool) 3497{ 3498 svn_wc_context_t *wc_ctx; 3499 const char *local_abspath; 3500 svn_error_t *err; 3501 3502 /* Subversion <= 1.6 said that '.' or a drive root is a WC root. */ 3503 if (svn_path_is_empty(path) || svn_dirent_is_root(path, strlen(path))) 3504 { 3505 *wc_root = TRUE; 3506 return SVN_NO_ERROR; 3507 } 3508 3509 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 3510 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 3511 svn_wc__adm_get_db(adm_access), 3512 pool)); 3513 3514 err = svn_wc_is_wc_root2(wc_root, wc_ctx, local_abspath, pool); 3515 3516 if (err 3517 && (err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY 3518 || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)) 3519 { 3520 /* Subversion <= 1.6 said that an unversioned path is a WC root. */ 3521 svn_error_clear(err); 3522 *wc_root = TRUE; 3523 } 3524 else 3525 SVN_ERR(err); 3526 3527 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 3528} 3529 3530 3531svn_error_t * 3532svn_wc_get_update_editor4(const svn_delta_editor_t **editor, 3533 void **edit_baton, 3534 svn_revnum_t *target_revision, 3535 svn_wc_context_t *wc_ctx, 3536 const char *anchor_abspath, 3537 const char *target_basename, 3538 svn_boolean_t use_commit_times, 3539 svn_depth_t depth, 3540 svn_boolean_t depth_is_sticky, 3541 svn_boolean_t allow_unver_obstructions, 3542 svn_boolean_t adds_as_modification, 3543 svn_boolean_t server_performs_filtering, 3544 svn_boolean_t clean_checkout, 3545 const char *diff3_cmd, 3546 const apr_array_header_t *preserved_exts, 3547 svn_wc_dirents_func_t fetch_dirents_func, 3548 void *fetch_dirents_baton, 3549 svn_wc_conflict_resolver_func2_t conflict_func, 3550 void *conflict_baton, 3551 svn_wc_external_update_t external_func, 3552 void *external_baton, 3553 svn_cancel_func_t cancel_func, 3554 void *cancel_baton, 3555 svn_wc_notify_func2_t notify_func, 3556 void *notify_baton, 3557 apr_pool_t *result_pool, 3558 apr_pool_t *scratch_pool) 3559{ 3560 return svn_error_trace( 3561 svn_wc__get_update_editor(editor, edit_baton, 3562 target_revision, 3563 wc_ctx, 3564 anchor_abspath, 3565 target_basename, NULL, 3566 use_commit_times, 3567 depth, depth_is_sticky, 3568 allow_unver_obstructions, 3569 adds_as_modification, 3570 server_performs_filtering, 3571 clean_checkout, 3572 diff3_cmd, 3573 preserved_exts, 3574 fetch_dirents_func, fetch_dirents_baton, 3575 conflict_func, conflict_baton, 3576 external_func, external_baton, 3577 cancel_func, cancel_baton, 3578 notify_func, notify_baton, 3579 result_pool, scratch_pool)); 3580} 3581 3582 3583svn_error_t * 3584svn_wc_get_update_editor3(svn_revnum_t *target_revision, 3585 svn_wc_adm_access_t *anchor, 3586 const char *target, 3587 svn_boolean_t use_commit_times, 3588 svn_depth_t depth, 3589 svn_boolean_t depth_is_sticky, 3590 svn_boolean_t allow_unver_obstructions, 3591 svn_wc_notify_func2_t notify_func, 3592 void *notify_baton, 3593 svn_cancel_func_t cancel_func, 3594 void *cancel_baton, 3595 svn_wc_conflict_resolver_func_t conflict_func, 3596 void *conflict_baton, 3597 svn_wc_get_file_t fetch_func, 3598 void *fetch_baton, 3599 const char *diff3_cmd, 3600 const apr_array_header_t *preserved_exts, 3601 const svn_delta_editor_t **editor, 3602 void **edit_baton, 3603 svn_wc_traversal_info_t *traversal_info, 3604 apr_pool_t *pool) 3605{ 3606 svn_wc_context_t *wc_ctx; 3607 svn_wc__db_t *db = svn_wc__adm_get_db(anchor); 3608 svn_wc_external_update_t external_func = NULL; 3609 struct traversal_info_update_baton *eb = NULL; 3610 struct conflict_func_1to2_baton *cfw = NULL; 3611 3612 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 3613 3614 if (traversal_info) 3615 { 3616 eb = apr_palloc(pool, sizeof(*eb)); 3617 eb->db = db; 3618 eb->traversal = traversal_info; 3619 external_func = traversal_info_update; 3620 } 3621 3622 if (conflict_func) 3623 { 3624 cfw = apr_pcalloc(pool, sizeof(*cfw)); 3625 cfw->inner_func = conflict_func; 3626 cfw->inner_baton = conflict_baton; 3627 } 3628 3629 if (diff3_cmd) 3630 SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool)); 3631 3632 SVN_ERR(svn_wc_get_update_editor4(editor, edit_baton, 3633 target_revision, 3634 wc_ctx, 3635 svn_wc__adm_access_abspath(anchor), 3636 target, 3637 use_commit_times, 3638 depth, depth_is_sticky, 3639 allow_unver_obstructions, 3640 TRUE /* adds_as_modification */, 3641 FALSE /* server_performs_filtering */, 3642 FALSE /* clean_checkout */, 3643 diff3_cmd, 3644 preserved_exts, 3645 NULL, NULL, /* fetch_dirents_func, baton */ 3646 conflict_func ? conflict_func_1to2_wrapper 3647 : NULL, 3648 cfw, 3649 external_func, eb, 3650 cancel_func, cancel_baton, 3651 notify_func, notify_baton, 3652 pool, pool)); 3653 3654 /* We can't destroy wc_ctx here, because the editor needs it while it's 3655 driven. */ 3656 return SVN_NO_ERROR; 3657} 3658 3659svn_error_t * 3660svn_wc_get_update_editor2(svn_revnum_t *target_revision, 3661 svn_wc_adm_access_t *anchor, 3662 const char *target, 3663 svn_boolean_t use_commit_times, 3664 svn_boolean_t recurse, 3665 svn_wc_notify_func2_t notify_func, 3666 void *notify_baton, 3667 svn_cancel_func_t cancel_func, 3668 void *cancel_baton, 3669 const char *diff3_cmd, 3670 const svn_delta_editor_t **editor, 3671 void **edit_baton, 3672 svn_wc_traversal_info_t *traversal_info, 3673 apr_pool_t *pool) 3674{ 3675 return svn_wc_get_update_editor3(target_revision, anchor, target, 3676 use_commit_times, 3677 SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE, 3678 FALSE, notify_func, notify_baton, 3679 cancel_func, cancel_baton, NULL, NULL, 3680 NULL, NULL, 3681 diff3_cmd, NULL, editor, edit_baton, 3682 traversal_info, pool); 3683} 3684 3685svn_error_t * 3686svn_wc_get_update_editor(svn_revnum_t *target_revision, 3687 svn_wc_adm_access_t *anchor, 3688 const char *target, 3689 svn_boolean_t use_commit_times, 3690 svn_boolean_t recurse, 3691 svn_wc_notify_func_t notify_func, 3692 void *notify_baton, 3693 svn_cancel_func_t cancel_func, 3694 void *cancel_baton, 3695 const char *diff3_cmd, 3696 const svn_delta_editor_t **editor, 3697 void **edit_baton, 3698 svn_wc_traversal_info_t *traversal_info, 3699 apr_pool_t *pool) 3700{ 3701 /* This baton must live beyond this function. Alloc on heap. */ 3702 struct compat_notify_baton_t *nb = apr_palloc(pool, sizeof(*nb)); 3703 3704 nb->func = notify_func; 3705 nb->baton = notify_baton; 3706 3707 return svn_wc_get_update_editor3(target_revision, anchor, target, 3708 use_commit_times, 3709 SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE, 3710 FALSE, compat_call_notify_func, nb, 3711 cancel_func, cancel_baton, NULL, NULL, 3712 NULL, NULL, 3713 diff3_cmd, NULL, editor, edit_baton, 3714 traversal_info, pool); 3715} 3716 3717 3718svn_error_t * 3719svn_wc_get_switch_editor4(const svn_delta_editor_t **editor, 3720 void **edit_baton, 3721 svn_revnum_t *target_revision, 3722 svn_wc_context_t *wc_ctx, 3723 const char *anchor_abspath, 3724 const char *target_basename, 3725 const char *switch_url, 3726 svn_boolean_t use_commit_times, 3727 svn_depth_t depth, 3728 svn_boolean_t depth_is_sticky, 3729 svn_boolean_t allow_unver_obstructions, 3730 svn_boolean_t server_performs_filtering, 3731 const char *diff3_cmd, 3732 const apr_array_header_t *preserved_exts, 3733 svn_wc_dirents_func_t fetch_dirents_func, 3734 void *fetch_dirents_baton, 3735 svn_wc_conflict_resolver_func2_t conflict_func, 3736 void *conflict_baton, 3737 svn_wc_external_update_t external_func, 3738 void *external_baton, 3739 svn_cancel_func_t cancel_func, 3740 void *cancel_baton, 3741 svn_wc_notify_func2_t notify_func, 3742 void *notify_baton, 3743 apr_pool_t *result_pool, 3744 apr_pool_t *scratch_pool) 3745{ 3746 return svn_error_trace( 3747 svn_wc__get_switch_editor(editor, edit_baton, 3748 target_revision, 3749 wc_ctx, 3750 anchor_abspath, target_basename, 3751 switch_url, NULL, 3752 use_commit_times, 3753 depth, depth_is_sticky, 3754 allow_unver_obstructions, 3755 server_performs_filtering, 3756 diff3_cmd, 3757 preserved_exts, 3758 fetch_dirents_func, fetch_dirents_baton, 3759 conflict_func, conflict_baton, 3760 external_func, external_baton, 3761 cancel_func, cancel_baton, 3762 notify_func, notify_baton, 3763 result_pool, scratch_pool)); 3764} 3765 3766 3767svn_error_t * 3768svn_wc_get_switch_editor3(svn_revnum_t *target_revision, 3769 svn_wc_adm_access_t *anchor, 3770 const char *target, 3771 const char *switch_url, 3772 svn_boolean_t use_commit_times, 3773 svn_depth_t depth, 3774 svn_boolean_t depth_is_sticky, 3775 svn_boolean_t allow_unver_obstructions, 3776 svn_wc_notify_func2_t notify_func, 3777 void *notify_baton, 3778 svn_cancel_func_t cancel_func, 3779 void *cancel_baton, 3780 svn_wc_conflict_resolver_func_t conflict_func, 3781 void *conflict_baton, 3782 const char *diff3_cmd, 3783 const apr_array_header_t *preserved_exts, 3784 const svn_delta_editor_t **editor, 3785 void **edit_baton, 3786 svn_wc_traversal_info_t *traversal_info, 3787 apr_pool_t *pool) 3788{ 3789 svn_wc_context_t *wc_ctx; 3790 svn_wc__db_t *db = svn_wc__adm_get_db(anchor); 3791 svn_wc_external_update_t external_func = NULL; 3792 struct traversal_info_update_baton *eb = NULL; 3793 struct conflict_func_1to2_baton *cfw = NULL; 3794 3795 SVN_ERR_ASSERT(switch_url && svn_uri_is_canonical(switch_url, pool)); 3796 3797 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 3798 3799 if (traversal_info) 3800 { 3801 eb = apr_palloc(pool, sizeof(*eb)); 3802 eb->db = db; 3803 eb->traversal = traversal_info; 3804 external_func = traversal_info_update; 3805 } 3806 3807 if (conflict_func) 3808 { 3809 cfw = apr_pcalloc(pool, sizeof(*cfw)); 3810 cfw->inner_func = conflict_func; 3811 cfw->inner_baton = conflict_baton; 3812 } 3813 3814 if (diff3_cmd) 3815 SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool)); 3816 3817 SVN_ERR(svn_wc_get_switch_editor4(editor, edit_baton, 3818 target_revision, 3819 wc_ctx, 3820 svn_wc__adm_access_abspath(anchor), 3821 target, switch_url, 3822 use_commit_times, 3823 depth, depth_is_sticky, 3824 allow_unver_obstructions, 3825 FALSE /* server_performs_filtering */, 3826 diff3_cmd, 3827 preserved_exts, 3828 NULL, NULL, /* fetch_dirents_func, baton */ 3829 conflict_func ? conflict_func_1to2_wrapper 3830 : NULL, 3831 cfw, 3832 external_func, eb, 3833 cancel_func, cancel_baton, 3834 notify_func, notify_baton, 3835 pool, pool)); 3836 3837 /* We can't destroy wc_ctx here, because the editor needs it while it's 3838 driven. */ 3839 return SVN_NO_ERROR; 3840} 3841 3842svn_error_t * 3843svn_wc_get_switch_editor2(svn_revnum_t *target_revision, 3844 svn_wc_adm_access_t *anchor, 3845 const char *target, 3846 const char *switch_url, 3847 svn_boolean_t use_commit_times, 3848 svn_boolean_t recurse, 3849 svn_wc_notify_func2_t notify_func, 3850 void *notify_baton, 3851 svn_cancel_func_t cancel_func, 3852 void *cancel_baton, 3853 const char *diff3_cmd, 3854 const svn_delta_editor_t **editor, 3855 void **edit_baton, 3856 svn_wc_traversal_info_t *traversal_info, 3857 apr_pool_t *pool) 3858{ 3859 SVN_ERR_ASSERT(switch_url); 3860 3861 return svn_wc_get_switch_editor3(target_revision, anchor, target, 3862 switch_url, use_commit_times, 3863 SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE, 3864 FALSE, notify_func, notify_baton, 3865 cancel_func, cancel_baton, 3866 NULL, NULL, diff3_cmd, 3867 NULL, editor, edit_baton, traversal_info, 3868 pool); 3869} 3870 3871svn_error_t * 3872svn_wc_get_switch_editor(svn_revnum_t *target_revision, 3873 svn_wc_adm_access_t *anchor, 3874 const char *target, 3875 const char *switch_url, 3876 svn_boolean_t use_commit_times, 3877 svn_boolean_t recurse, 3878 svn_wc_notify_func_t notify_func, 3879 void *notify_baton, 3880 svn_cancel_func_t cancel_func, 3881 void *cancel_baton, 3882 const char *diff3_cmd, 3883 const svn_delta_editor_t **editor, 3884 void **edit_baton, 3885 svn_wc_traversal_info_t *traversal_info, 3886 apr_pool_t *pool) 3887{ 3888 /* This baton must live beyond this function. Alloc on heap. */ 3889 struct compat_notify_baton_t *nb = apr_palloc(pool, sizeof(*nb)); 3890 3891 nb->func = notify_func; 3892 nb->baton = notify_baton; 3893 3894 return svn_wc_get_switch_editor3(target_revision, anchor, target, 3895 switch_url, use_commit_times, 3896 SVN_DEPTH_INFINITY_OR_FILES(recurse), FALSE, 3897 FALSE, compat_call_notify_func, nb, 3898 cancel_func, cancel_baton, 3899 NULL, NULL, diff3_cmd, 3900 NULL, editor, edit_baton, traversal_info, 3901 pool); 3902} 3903 3904 3905svn_error_t * 3906svn_wc_external_item_create(const svn_wc_external_item2_t **item, 3907 apr_pool_t *pool) 3908{ 3909 *item = apr_pcalloc(pool, sizeof(svn_wc_external_item2_t)); 3910 return SVN_NO_ERROR; 3911} 3912 3913svn_wc_external_item_t * 3914svn_wc_external_item_dup(const svn_wc_external_item_t *item, 3915 apr_pool_t *pool) 3916{ 3917 svn_wc_external_item_t *new_item = apr_palloc(pool, sizeof(*new_item)); 3918 3919 *new_item = *item; 3920 3921 if (new_item->target_dir) 3922 new_item->target_dir = apr_pstrdup(pool, new_item->target_dir); 3923 3924 if (new_item->url) 3925 new_item->url = apr_pstrdup(pool, new_item->url); 3926 3927 return new_item; 3928} 3929 3930 3931svn_wc_traversal_info_t * 3932svn_wc_init_traversal_info(apr_pool_t *pool) 3933{ 3934 svn_wc_traversal_info_t *ti = apr_palloc(pool, sizeof(*ti)); 3935 3936 ti->pool = pool; 3937 ti->externals_old = apr_hash_make(pool); 3938 ti->externals_new = apr_hash_make(pool); 3939 ti->depths = apr_hash_make(pool); 3940 3941 return ti; 3942} 3943 3944 3945void 3946svn_wc_edited_externals(apr_hash_t **externals_old, 3947 apr_hash_t **externals_new, 3948 svn_wc_traversal_info_t *traversal_info) 3949{ 3950 *externals_old = traversal_info->externals_old; 3951 *externals_new = traversal_info->externals_new; 3952} 3953 3954 3955void 3956svn_wc_traversed_depths(apr_hash_t **depths, 3957 svn_wc_traversal_info_t *traversal_info) 3958{ 3959 *depths = traversal_info->depths; 3960} 3961 3962 3963/*** From lock.c ***/ 3964 3965/* To preserve API compatibility with Subversion 1.0.0 */ 3966svn_error_t * 3967svn_wc_adm_open(svn_wc_adm_access_t **adm_access, 3968 svn_wc_adm_access_t *associated, 3969 const char *path, 3970 svn_boolean_t write_lock, 3971 svn_boolean_t tree_lock, 3972 apr_pool_t *pool) 3973{ 3974 return svn_wc_adm_open3(adm_access, associated, path, write_lock, 3975 (tree_lock ? -1 : 0), NULL, NULL, pool); 3976} 3977 3978svn_error_t * 3979svn_wc_adm_open2(svn_wc_adm_access_t **adm_access, 3980 svn_wc_adm_access_t *associated, 3981 const char *path, 3982 svn_boolean_t write_lock, 3983 int levels_to_lock, 3984 apr_pool_t *pool) 3985{ 3986 return svn_wc_adm_open3(adm_access, associated, path, write_lock, 3987 levels_to_lock, NULL, NULL, pool); 3988} 3989 3990svn_error_t * 3991svn_wc_adm_probe_open(svn_wc_adm_access_t **adm_access, 3992 svn_wc_adm_access_t *associated, 3993 const char *path, 3994 svn_boolean_t write_lock, 3995 svn_boolean_t tree_lock, 3996 apr_pool_t *pool) 3997{ 3998 return svn_wc_adm_probe_open3(adm_access, associated, path, 3999 write_lock, (tree_lock ? -1 : 0), 4000 NULL, NULL, pool); 4001} 4002 4003 4004svn_error_t * 4005svn_wc_adm_probe_open2(svn_wc_adm_access_t **adm_access, 4006 svn_wc_adm_access_t *associated, 4007 const char *path, 4008 svn_boolean_t write_lock, 4009 int levels_to_lock, 4010 apr_pool_t *pool) 4011{ 4012 return svn_wc_adm_probe_open3(adm_access, associated, path, write_lock, 4013 levels_to_lock, NULL, NULL, pool); 4014} 4015 4016svn_error_t * 4017svn_wc_adm_probe_try2(svn_wc_adm_access_t **adm_access, 4018 svn_wc_adm_access_t *associated, 4019 const char *path, 4020 svn_boolean_t write_lock, 4021 int levels_to_lock, 4022 apr_pool_t *pool) 4023{ 4024 return svn_wc_adm_probe_try3(adm_access, associated, path, write_lock, 4025 levels_to_lock, NULL, NULL, pool); 4026} 4027 4028svn_error_t * 4029svn_wc_adm_probe_try(svn_wc_adm_access_t **adm_access, 4030 svn_wc_adm_access_t *associated, 4031 const char *path, 4032 svn_boolean_t write_lock, 4033 svn_boolean_t tree_lock, 4034 apr_pool_t *pool) 4035{ 4036 return svn_wc_adm_probe_try3(adm_access, associated, path, write_lock, 4037 (tree_lock ? -1 : 0), NULL, NULL, pool); 4038} 4039 4040svn_error_t * 4041svn_wc_adm_close(svn_wc_adm_access_t *adm_access) 4042{ 4043 /* This is the only pool we have access to. */ 4044 apr_pool_t *scratch_pool = svn_wc_adm_access_pool(adm_access); 4045 4046 return svn_wc_adm_close2(adm_access, scratch_pool); 4047} 4048 4049svn_error_t * 4050svn_wc_locked(svn_boolean_t *locked, 4051 const char *path, 4052 apr_pool_t *pool) 4053{ 4054 svn_wc_context_t *wc_ctx; 4055 const char *local_abspath; 4056 4057 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4058 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool)); 4059 4060 SVN_ERR(svn_wc_locked2(NULL, locked, wc_ctx, local_abspath, pool)); 4061 4062 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4063} 4064 4065svn_error_t * 4066svn_wc_check_wc(const char *path, 4067 int *wc_format, 4068 apr_pool_t *pool) 4069{ 4070 svn_wc_context_t *wc_ctx; 4071 const char *local_abspath; 4072 4073 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4074 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool)); 4075 4076 SVN_ERR(svn_wc_check_wc2(wc_format, wc_ctx, local_abspath, pool)); 4077 4078 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4079} 4080 4081 4082/*** From translate.c ***/ 4083 4084svn_error_t * 4085svn_wc_translated_file(const char **xlated_p, 4086 const char *vfile, 4087 svn_wc_adm_access_t *adm_access, 4088 svn_boolean_t force_repair, 4089 apr_pool_t *pool) 4090{ 4091 return svn_wc_translated_file2(xlated_p, vfile, vfile, adm_access, 4092 SVN_WC_TRANSLATE_TO_NF 4093 | (force_repair ? 4094 SVN_WC_TRANSLATE_FORCE_EOL_REPAIR : 0), 4095 pool); 4096} 4097 4098svn_error_t * 4099svn_wc_translated_stream(svn_stream_t **stream, 4100 const char *path, 4101 const char *versioned_file, 4102 svn_wc_adm_access_t *adm_access, 4103 apr_uint32_t flags, 4104 apr_pool_t *pool) 4105{ 4106 const char *local_abspath; 4107 const char *versioned_abspath; 4108 4109 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4110 SVN_ERR(svn_dirent_get_absolute(&versioned_abspath, versioned_file, pool)); 4111 4112 return svn_error_trace( 4113 svn_wc__internal_translated_stream(stream, svn_wc__adm_get_db(adm_access), 4114 local_abspath, versioned_abspath, flags, 4115 pool, pool)); 4116} 4117 4118svn_error_t * 4119svn_wc_translated_file2(const char **xlated_path, 4120 const char *src, 4121 const char *versioned_file, 4122 svn_wc_adm_access_t *adm_access, 4123 apr_uint32_t flags, 4124 apr_pool_t *pool) 4125{ 4126 const char *versioned_abspath; 4127 const char *root; 4128 const char *tmp_root; 4129 const char *src_abspath; 4130 4131 SVN_ERR(svn_dirent_get_absolute(&versioned_abspath, versioned_file, pool)); 4132 SVN_ERR(svn_dirent_get_absolute(&src_abspath, src, pool)); 4133 4134 SVN_ERR(svn_wc__internal_translated_file(xlated_path, src_abspath, 4135 svn_wc__adm_get_db(adm_access), 4136 versioned_abspath, 4137 flags, NULL, NULL, pool, pool)); 4138 4139 if (strcmp(*xlated_path, src_abspath) == 0) 4140 *xlated_path = src; 4141 else if (! svn_dirent_is_absolute(versioned_file)) 4142 { 4143 SVN_ERR(svn_io_temp_dir(&tmp_root, pool)); 4144 if (! svn_dirent_is_child(tmp_root, *xlated_path, pool)) 4145 { 4146 SVN_ERR(svn_dirent_get_absolute(&root, "", pool)); 4147 4148 if (svn_dirent_is_child(root, *xlated_path, pool)) 4149 *xlated_path = svn_dirent_is_child(root, *xlated_path, pool); 4150 } 4151 } 4152 4153 return SVN_NO_ERROR; 4154} 4155 4156/*** From relocate.c ***/ 4157svn_error_t * 4158svn_wc_relocate3(const char *path, 4159 svn_wc_adm_access_t *adm_access, 4160 const char *from, 4161 const char *to, 4162 svn_boolean_t recurse, 4163 svn_wc_relocation_validator3_t validator, 4164 void *validator_baton, 4165 apr_pool_t *pool) 4166{ 4167 const char *local_abspath; 4168 svn_wc_context_t *wc_ctx; 4169 4170 if (! recurse) 4171 SVN_ERR(svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, 4172 _("Non-recursive relocation not supported"))); 4173 4174 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4175 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 4176 svn_wc__adm_get_db(adm_access), 4177 pool)); 4178 4179 SVN_ERR(svn_wc_relocate4(wc_ctx, local_abspath, from, to, 4180 validator, validator_baton, pool)); 4181 4182 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4183} 4184 4185/* Compatibility baton and wrapper. */ 4186struct compat2_baton { 4187 svn_wc_relocation_validator2_t validator; 4188 void *baton; 4189}; 4190 4191/* Compatibility baton and wrapper. */ 4192struct compat_baton { 4193 svn_wc_relocation_validator_t validator; 4194 void *baton; 4195}; 4196 4197/* This implements svn_wc_relocate_validator3_t. */ 4198static svn_error_t * 4199compat2_validator(void *baton, 4200 const char *uuid, 4201 const char *url, 4202 const char *root_url, 4203 apr_pool_t *pool) 4204{ 4205 struct compat2_baton *cb = baton; 4206 /* The old callback type doesn't set root_url. */ 4207 return cb->validator(cb->baton, uuid, 4208 (root_url ? root_url : url), (root_url != NULL), 4209 pool); 4210} 4211 4212/* This implements svn_wc_relocate_validator3_t. */ 4213static svn_error_t * 4214compat_validator(void *baton, 4215 const char *uuid, 4216 const char *url, 4217 const char *root_url, 4218 apr_pool_t *pool) 4219{ 4220 struct compat_baton *cb = baton; 4221 /* The old callback type doesn't allow uuid to be NULL. */ 4222 if (uuid) 4223 return cb->validator(cb->baton, uuid, url); 4224 return SVN_NO_ERROR; 4225} 4226 4227svn_error_t * 4228svn_wc_relocate2(const char *path, 4229 svn_wc_adm_access_t *adm_access, 4230 const char *from, 4231 const char *to, 4232 svn_boolean_t recurse, 4233 svn_wc_relocation_validator2_t validator, 4234 void *validator_baton, 4235 apr_pool_t *pool) 4236{ 4237 struct compat2_baton cb; 4238 4239 cb.validator = validator; 4240 cb.baton = validator_baton; 4241 4242 return svn_wc_relocate3(path, adm_access, from, to, recurse, 4243 compat2_validator, &cb, pool); 4244} 4245 4246svn_error_t * 4247svn_wc_relocate(const char *path, 4248 svn_wc_adm_access_t *adm_access, 4249 const char *from, 4250 const char *to, 4251 svn_boolean_t recurse, 4252 svn_wc_relocation_validator_t validator, 4253 void *validator_baton, 4254 apr_pool_t *pool) 4255{ 4256 struct compat_baton cb; 4257 4258 cb.validator = validator; 4259 cb.baton = validator_baton; 4260 4261 return svn_wc_relocate3(path, adm_access, from, to, recurse, 4262 compat_validator, &cb, pool); 4263} 4264 4265 4266/*** From log.c / cleanup.c ***/ 4267 4268svn_error_t * 4269svn_wc_cleanup3(svn_wc_context_t *wc_ctx, 4270 const char *local_abspath, 4271 svn_cancel_func_t cancel_func, 4272 void *cancel_baton, 4273 apr_pool_t *scratch_pool) 4274{ 4275 return svn_error_trace( 4276 svn_wc_cleanup4(wc_ctx, 4277 local_abspath, 4278 TRUE /* break_locks */, 4279 TRUE /* fix_recorded_timestamps */, 4280 TRUE /* clear_dav_cache */, 4281 TRUE /* clean_pristines */, 4282 cancel_func, cancel_baton, 4283 NULL, NULL /* notify */, 4284 scratch_pool)); 4285} 4286 4287svn_error_t * 4288svn_wc_cleanup2(const char *path, 4289 const char *diff3_cmd, 4290 svn_cancel_func_t cancel_func, 4291 void *cancel_baton, 4292 apr_pool_t *pool) 4293{ 4294 svn_wc_context_t *wc_ctx; 4295 const char *local_abspath; 4296 4297 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4298 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool)); 4299 4300 SVN_ERR(svn_wc_cleanup3(wc_ctx, local_abspath, cancel_func, 4301 cancel_baton, pool)); 4302 4303 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4304} 4305 4306svn_error_t * 4307svn_wc_cleanup(const char *path, 4308 svn_wc_adm_access_t *optional_adm_access, 4309 const char *diff3_cmd, 4310 svn_cancel_func_t cancel_func, 4311 void *cancel_baton, 4312 apr_pool_t *pool) 4313{ 4314 return svn_wc_cleanup2(path, diff3_cmd, cancel_func, cancel_baton, pool); 4315} 4316 4317/*** From questions.c ***/ 4318 4319svn_error_t * 4320svn_wc_has_binary_prop(svn_boolean_t *has_binary_prop, 4321 const char *path, 4322 svn_wc_adm_access_t *adm_access, 4323 apr_pool_t *pool) 4324{ 4325 svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); 4326 const char *local_abspath; 4327 const svn_string_t *value; 4328 4329 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4330 4331 SVN_ERR(svn_wc__internal_propget(&value, db, local_abspath, 4332 SVN_PROP_MIME_TYPE, 4333 pool, pool)); 4334 4335 if (value && (svn_mime_type_is_binary(value->data))) 4336 *has_binary_prop = TRUE; 4337 else 4338 *has_binary_prop = FALSE; 4339 4340 return SVN_NO_ERROR; 4341} 4342 4343svn_error_t * 4344svn_wc_conflicted_p2(svn_boolean_t *text_conflicted_p, 4345 svn_boolean_t *prop_conflicted_p, 4346 svn_boolean_t *tree_conflicted_p, 4347 const char *path, 4348 svn_wc_adm_access_t *adm_access, 4349 apr_pool_t *pool) 4350{ 4351 const char *local_abspath; 4352 svn_wc_context_t *wc_ctx; 4353 svn_error_t *err; 4354 4355 SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); 4356 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, 4357 svn_wc__adm_get_db(adm_access), 4358 pool)); 4359 4360 err = svn_wc_conflicted_p3(text_conflicted_p, prop_conflicted_p, 4361 tree_conflicted_p, wc_ctx, local_abspath, pool); 4362 4363 if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) 4364 { 4365 svn_error_clear(err); 4366 4367 if (text_conflicted_p) 4368 *text_conflicted_p = FALSE; 4369 if (prop_conflicted_p) 4370 *prop_conflicted_p = FALSE; 4371 if (tree_conflicted_p) 4372 *tree_conflicted_p = FALSE; 4373 } 4374 else if (err) 4375 return err; 4376 4377 return SVN_NO_ERROR; 4378} 4379 4380svn_error_t * 4381svn_wc_conflicted_p(svn_boolean_t *text_conflicted_p, 4382 svn_boolean_t *prop_conflicted_p, 4383 const char *dir_path, 4384 const svn_wc_entry_t *entry, 4385 apr_pool_t *pool) 4386{ 4387 svn_node_kind_t kind; 4388 const char *path; 4389 4390 *text_conflicted_p = FALSE; 4391 *prop_conflicted_p = FALSE; 4392 4393 if (entry->conflict_old) 4394 { 4395 path = svn_dirent_join(dir_path, entry->conflict_old, pool); 4396 SVN_ERR(svn_io_check_path(path, &kind, pool)); 4397 *text_conflicted_p = (kind == svn_node_file); 4398 } 4399 4400 if ((! *text_conflicted_p) && (entry->conflict_new)) 4401 { 4402 path = svn_dirent_join(dir_path, entry->conflict_new, pool); 4403 SVN_ERR(svn_io_check_path(path, &kind, pool)); 4404 *text_conflicted_p = (kind == svn_node_file); 4405 } 4406 4407 if ((! *text_conflicted_p) && (entry->conflict_wrk)) 4408 { 4409 path = svn_dirent_join(dir_path, entry->conflict_wrk, pool); 4410 SVN_ERR(svn_io_check_path(path, &kind, pool)); 4411 *text_conflicted_p = (kind == svn_node_file); 4412 } 4413 4414 if (entry->prejfile) 4415 { 4416 path = svn_dirent_join(dir_path, entry->prejfile, pool); 4417 SVN_ERR(svn_io_check_path(path, &kind, pool)); 4418 *prop_conflicted_p = (kind == svn_node_file); 4419 } 4420 4421 return SVN_NO_ERROR; 4422} 4423 4424svn_error_t * 4425svn_wc_text_modified_p(svn_boolean_t *modified_p, 4426 const char *filename, 4427 svn_boolean_t force_comparison, 4428 svn_wc_adm_access_t *adm_access, 4429 apr_pool_t *pool) 4430{ 4431 svn_wc_context_t *wc_ctx; 4432 svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); 4433 const char *local_abspath; 4434 4435 SVN_ERR(svn_dirent_get_absolute(&local_abspath, filename, pool)); 4436 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 4437 4438 SVN_ERR(svn_wc_text_modified_p2(modified_p, wc_ctx, local_abspath, 4439 force_comparison, pool)); 4440 4441 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4442} 4443 4444 4445/*** From copy.c ***/ 4446svn_error_t * 4447svn_wc_copy2(const char *src, 4448 svn_wc_adm_access_t *dst_parent, 4449 const char *dst_basename, 4450 svn_cancel_func_t cancel_func, 4451 void *cancel_baton, 4452 svn_wc_notify_func2_t notify_func, 4453 void *notify_baton, 4454 apr_pool_t *pool) 4455{ 4456 svn_wc_context_t *wc_ctx; 4457 svn_wc__db_t *wc_db = svn_wc__adm_get_db(dst_parent); 4458 const char *src_abspath; 4459 const char *dst_abspath; 4460 4461 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, wc_db, pool)); 4462 SVN_ERR(svn_dirent_get_absolute(&src_abspath, src, pool)); 4463 4464 dst_abspath = svn_dirent_join(svn_wc__adm_access_abspath(dst_parent), 4465 dst_basename, pool); 4466 4467 SVN_ERR(svn_wc_copy3(wc_ctx, 4468 src_abspath, 4469 dst_abspath, 4470 FALSE /* metadata_only */, 4471 cancel_func, cancel_baton, 4472 notify_func, notify_baton, 4473 pool)); 4474 4475 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4476} 4477 4478svn_error_t * 4479svn_wc_copy(const char *src_path, 4480 svn_wc_adm_access_t *dst_parent, 4481 const char *dst_basename, 4482 svn_cancel_func_t cancel_func, 4483 void *cancel_baton, 4484 svn_wc_notify_func_t notify_func, 4485 void *notify_baton, 4486 apr_pool_t *pool) 4487{ 4488 struct compat_notify_baton_t nb; 4489 4490 nb.func = notify_func; 4491 nb.baton = notify_baton; 4492 4493 return svn_wc_copy2(src_path, dst_parent, dst_basename, cancel_func, 4494 cancel_baton, compat_call_notify_func, 4495 &nb, pool); 4496} 4497 4498 4499/*** From merge.c ***/ 4500 4501svn_error_t * 4502svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome, 4503 svn_wc_context_t *wc_ctx, 4504 const char *left_abspath, 4505 const char *right_abspath, 4506 const char *target_abspath, 4507 const char *left_label, 4508 const char *right_label, 4509 const char *target_label, 4510 const svn_wc_conflict_version_t *left_version, 4511 const svn_wc_conflict_version_t *right_version, 4512 svn_boolean_t dry_run, 4513 const char *diff3_cmd, 4514 const apr_array_header_t *merge_options, 4515 const apr_array_header_t *prop_diff, 4516 svn_wc_conflict_resolver_func2_t conflict_func, 4517 void *conflict_baton, 4518 svn_cancel_func_t cancel_func, 4519 void *cancel_baton, 4520 apr_pool_t *scratch_pool) 4521{ 4522 return svn_error_trace( 4523 svn_wc_merge5(merge_outcome, 4524 NULL /* merge_props_outcome */, 4525 wc_ctx, 4526 left_abspath, 4527 right_abspath, 4528 target_abspath, 4529 left_label, 4530 right_label, 4531 target_label, 4532 left_version, 4533 right_version, 4534 dry_run, 4535 diff3_cmd, 4536 merge_options, 4537 NULL /* original_props */, 4538 prop_diff, 4539 conflict_func, conflict_baton, 4540 cancel_func, cancel_baton, 4541 scratch_pool)); 4542} 4543 4544svn_error_t * 4545svn_wc_merge3(enum svn_wc_merge_outcome_t *merge_outcome, 4546 const char *left, 4547 const char *right, 4548 const char *merge_target, 4549 svn_wc_adm_access_t *adm_access, 4550 const char *left_label, 4551 const char *right_label, 4552 const char *target_label, 4553 svn_boolean_t dry_run, 4554 const char *diff3_cmd, 4555 const apr_array_header_t *merge_options, 4556 const apr_array_header_t *prop_diff, 4557 svn_wc_conflict_resolver_func_t conflict_func, 4558 void *conflict_baton, 4559 apr_pool_t *pool) 4560{ 4561 svn_wc_context_t *wc_ctx; 4562 svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); 4563 const char *left_abspath, *right_abspath, *target_abspath; 4564 struct conflict_func_1to2_baton cfw; 4565 4566 SVN_ERR(svn_dirent_get_absolute(&left_abspath, left, pool)); 4567 SVN_ERR(svn_dirent_get_absolute(&right_abspath, right, pool)); 4568 SVN_ERR(svn_dirent_get_absolute(&target_abspath, merge_target, pool)); 4569 4570 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, db, pool)); 4571 4572 cfw.inner_func = conflict_func; 4573 cfw.inner_baton = conflict_baton; 4574 4575 if (diff3_cmd) 4576 SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool)); 4577 4578 SVN_ERR(svn_wc_merge4(merge_outcome, 4579 wc_ctx, 4580 left_abspath, 4581 right_abspath, 4582 target_abspath, 4583 left_label, 4584 right_label, 4585 target_label, 4586 NULL, 4587 NULL, 4588 dry_run, 4589 diff3_cmd, 4590 merge_options, 4591 prop_diff, 4592 conflict_func ? conflict_func_1to2_wrapper : NULL, 4593 &cfw, 4594 NULL, NULL, 4595 pool)); 4596 4597 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4598} 4599 4600svn_error_t * 4601svn_wc_merge2(enum svn_wc_merge_outcome_t *merge_outcome, 4602 const char *left, 4603 const char *right, 4604 const char *merge_target, 4605 svn_wc_adm_access_t *adm_access, 4606 const char *left_label, 4607 const char *right_label, 4608 const char *target_label, 4609 svn_boolean_t dry_run, 4610 const char *diff3_cmd, 4611 const apr_array_header_t *merge_options, 4612 apr_pool_t *pool) 4613{ 4614 return svn_wc_merge3(merge_outcome, 4615 left, right, merge_target, adm_access, 4616 left_label, right_label, target_label, 4617 dry_run, diff3_cmd, merge_options, NULL, 4618 NULL, NULL, pool); 4619} 4620 4621svn_error_t * 4622svn_wc_merge(const char *left, 4623 const char *right, 4624 const char *merge_target, 4625 svn_wc_adm_access_t *adm_access, 4626 const char *left_label, 4627 const char *right_label, 4628 const char *target_label, 4629 svn_boolean_t dry_run, 4630 enum svn_wc_merge_outcome_t *merge_outcome, 4631 const char *diff3_cmd, 4632 apr_pool_t *pool) 4633{ 4634 return svn_wc_merge3(merge_outcome, 4635 left, right, merge_target, adm_access, 4636 left_label, right_label, target_label, 4637 dry_run, diff3_cmd, NULL, NULL, NULL, 4638 NULL, pool); 4639} 4640 4641 4642/*** From util.c ***/ 4643 4644svn_wc_conflict_version_t * 4645svn_wc_conflict_version_create(const char *repos_url, 4646 const char *path_in_repos, 4647 svn_revnum_t peg_rev, 4648 svn_node_kind_t node_kind, 4649 apr_pool_t *pool) 4650{ 4651 return svn_wc_conflict_version_create2(repos_url, NULL, path_in_repos, 4652 peg_rev, node_kind, pool); 4653} 4654 4655svn_wc_conflict_description_t * 4656svn_wc_conflict_description_create_text(const char *path, 4657 svn_wc_adm_access_t *adm_access, 4658 apr_pool_t *pool) 4659{ 4660 svn_wc_conflict_description_t *conflict; 4661 4662 conflict = apr_pcalloc(pool, sizeof(*conflict)); 4663 conflict->path = path; 4664 conflict->node_kind = svn_node_file; 4665 conflict->kind = svn_wc_conflict_kind_text; 4666 conflict->access = adm_access; 4667 conflict->action = svn_wc_conflict_action_edit; 4668 conflict->reason = svn_wc_conflict_reason_edited; 4669 return conflict; 4670} 4671 4672svn_wc_conflict_description_t * 4673svn_wc_conflict_description_create_prop(const char *path, 4674 svn_wc_adm_access_t *adm_access, 4675 svn_node_kind_t node_kind, 4676 const char *property_name, 4677 apr_pool_t *pool) 4678{ 4679 svn_wc_conflict_description_t *conflict; 4680 4681 conflict = apr_pcalloc(pool, sizeof(*conflict)); 4682 conflict->path = path; 4683 conflict->node_kind = node_kind; 4684 conflict->kind = svn_wc_conflict_kind_property; 4685 conflict->access = adm_access; 4686 conflict->property_name = property_name; 4687 return conflict; 4688} 4689 4690svn_wc_conflict_description_t * 4691svn_wc_conflict_description_create_tree( 4692 const char *path, 4693 svn_wc_adm_access_t *adm_access, 4694 svn_node_kind_t node_kind, 4695 svn_wc_operation_t operation, 4696 svn_wc_conflict_version_t *src_left_version, 4697 svn_wc_conflict_version_t *src_right_version, 4698 apr_pool_t *pool) 4699{ 4700 svn_wc_conflict_description_t *conflict; 4701 4702 conflict = apr_pcalloc(pool, sizeof(*conflict)); 4703 conflict->path = path; 4704 conflict->node_kind = node_kind; 4705 conflict->kind = svn_wc_conflict_kind_tree; 4706 conflict->access = adm_access; 4707 conflict->operation = operation; 4708 conflict->src_left_version = src_left_version; 4709 conflict->src_right_version = src_right_version; 4710 return conflict; 4711} 4712 4713 4714/*** From revision_status.c ***/ 4715 4716svn_error_t * 4717svn_wc_revision_status(svn_wc_revision_status_t **result_p, 4718 const char *wc_path, 4719 const char *trail_url, 4720 svn_boolean_t committed, 4721 svn_cancel_func_t cancel_func, 4722 void *cancel_baton, 4723 apr_pool_t *pool) 4724{ 4725 svn_wc_context_t *wc_ctx; 4726 const char *local_abspath; 4727 4728 SVN_ERR(svn_dirent_get_absolute(&local_abspath, wc_path, pool)); 4729 SVN_ERR(svn_wc_context_create(&wc_ctx, NULL /* config */, pool, pool)); 4730 4731 SVN_ERR(svn_wc_revision_status2(result_p, wc_ctx, local_abspath, trail_url, 4732 committed, cancel_func, cancel_baton, pool, 4733 pool)); 4734 4735 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4736} 4737 4738/*** From crop.c ***/ 4739svn_error_t * 4740svn_wc_crop_tree(svn_wc_adm_access_t *anchor, 4741 const char *target, 4742 svn_depth_t depth, 4743 svn_wc_notify_func2_t notify_func, 4744 void *notify_baton, 4745 svn_cancel_func_t cancel_func, 4746 void *cancel_baton, 4747 apr_pool_t *pool) 4748{ 4749 svn_wc_context_t *wc_ctx; 4750 svn_wc__db_t *db = svn_wc__adm_get_db(anchor); 4751 const char *local_abspath; 4752 4753 local_abspath = svn_dirent_join(svn_wc__adm_access_abspath(anchor), 4754 target, pool); 4755 4756 SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); 4757 4758 if (depth == svn_depth_exclude) 4759 { 4760 SVN_ERR(svn_wc_exclude(wc_ctx, 4761 local_abspath, 4762 cancel_func, cancel_baton, 4763 notify_func, notify_baton, 4764 pool)); 4765 } 4766 else 4767 { 4768 SVN_ERR(svn_wc_crop_tree2(wc_ctx, 4769 local_abspath, 4770 depth, 4771 cancel_func, cancel_baton, 4772 notify_func, notify_baton, 4773 pool)); 4774 } 4775 4776 return svn_error_trace(svn_wc_context_destroy(wc_ctx)); 4777} 4778 4779svn_error_t * 4780svn_wc_move(svn_wc_context_t *wc_ctx, 4781 const char *src_abspath, 4782 const char *dst_abspath, 4783 svn_boolean_t metadata_only, 4784 svn_cancel_func_t cancel_func, 4785 void *cancel_baton, 4786 svn_wc_notify_func2_t notify_func, 4787 void *notify_baton, 4788 apr_pool_t *scratch_pool) 4789{ 4790 return svn_error_trace(svn_wc__move2(wc_ctx, src_abspath, dst_abspath, 4791 metadata_only, 4792 TRUE, /* allow_mixed_revisions */ 4793 cancel_func, cancel_baton, 4794 notify_func, notify_baton, 4795 scratch_pool)); 4796} 4797 4798svn_error_t * 4799svn_wc_read_kind(svn_node_kind_t *kind, 4800 svn_wc_context_t *wc_ctx, 4801 const char *abspath, 4802 svn_boolean_t show_hidden, 4803 apr_pool_t *scratch_pool) 4804{ 4805 return svn_error_trace( 4806 svn_wc_read_kind2(kind, 4807 wc_ctx, abspath, 4808 TRUE /* show_deleted */, 4809 show_hidden, 4810 scratch_pool)); 4811} 4812 4813svn_wc_conflict_description2_t * 4814svn_wc__conflict_description2_dup(const svn_wc_conflict_description2_t *conflict, 4815 apr_pool_t *pool) 4816{ 4817 return svn_wc_conflict_description2_dup(conflict, pool); 4818} 4819