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