00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #include <errno.h>
00015 #include <time.h>
00016 #include <unistd.h>
00017
00018 #include <subversion-1/svn_ra.h>
00019 #include <subversion-1/svn_auth.h>
00020 #include <subversion-1/svn_client.h>
00021 #include <subversion-1/svn_cmdline.h>
00022
00023
00024
00025 #include "global.h"
00026 #include "helper.h"
00027 #include "update.h"
00028 #include "est_ops.h"
00029 #include "checksum.h"
00030 #include "status.h"
00031 #include "cache.h"
00032 #include "url.h"
00033 #include "racallback.h"
00034
00035
00036 svn_error_t *cb__init(apr_pool_t *pool)
00037 {
00038 int status;
00039 svn_error_t *status_svn;
00040 apr_hash_t *cfg_hash;
00041 svn_config_t *cfg;
00042
00043
00044 STOPIF( hlp__get_svn_config(&cfg_hash), NULL);
00045
00046 cfg = apr_hash_get(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG,
00047 APR_HASH_KEY_STRING);
00048
00049
00050
00051 STOPIF_SVNERR( svn_cmdline_setup_auth_baton,
00052 (&cb__cb_table.auth_baton,
00053 !(isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)),
00054 opt__get_int(OPT__AUTHOR) ?
00055 opt__get_string(OPT__AUTHOR) : NULL,
00056 NULL,
00057 opt__get_string(OPT__CONFIG_DIR),
00058 0,
00059 cfg,
00060 NULL,
00061 NULL,
00062 pool)
00063 );
00064
00065 BUG_ON(!cb__cb_table.auth_baton);
00066
00067 ex:
00068 RETURN_SVNERR(status);
00069 }
00070
00071
00072
00073
00074
00076
00078 svn_error_t *cb__open_tmp (apr_file_t **fp,
00079 void *callback_baton,
00080 apr_pool_t *pool)
00081 {
00082 int status;
00083
00084
00085 STOPIF( waa__get_tmp_name( NULL, NULL, fp, pool), NULL);
00086
00087 ex:
00088 RETURN_SVNERR(status);
00089 }
00090
00091
00092 struct svn_ra_callbacks_t cb__cb_table=
00093 {
00094 .open_tmp_file = cb__open_tmp,
00095 .auth_baton = NULL,
00096
00097 .get_wc_prop = NULL,
00098 .set_wc_prop=NULL,
00099 .push_wc_prop=NULL,
00100 .invalidate_wc_props=NULL,
00101 };
00102
00103
00104
00105
00106
00107
00108
00109
00110 svn_revnum_t cb___dest_rev;
00111
00113 svn_error_t *cb__txdelta_discard(svn_txdelta_window_t *window UNUSED,
00114 void *baton UNUSED)
00115 {
00116 return NULL;
00117 }
00118
00119
00130 int cb__add_entry(struct estat *dir,
00131 const char *utf8_path, char **loc_path,
00132 const char *utf8_copy_path,
00133 svn_revnum_t copy_rev,
00134 int mode,
00135 int *has_existed,
00136 int may_create,
00137 void **new)
00138 {
00139 int status;
00140 struct estat *sts;
00141 char *filename;
00142 char* path;
00143 char* copy_path;
00144 int overwrite;
00145 struct sstat_t st;
00146
00147
00148 overwrite=0;
00149 STOPIF( hlp__utf82local(utf8_path, &path, -1), NULL );
00150 if (loc_path) *loc_path=path;
00151 STOPIF( hlp__utf82local(utf8_copy_path, ©_path, -1), NULL );
00152
00153 STOPIF_CODE_ERR(copy_path, EINVAL,
00154 "don't know how to handle copy_path %s@%ld",
00155 copy_path, copy_rev);
00156
00157
00158
00159 filename = ops__get_filename(path);
00160 STOPIF( ops__find_entry_byname(dir, filename, &sts, 0),
00161 "cannot lookup entry %s", path);
00162 DEBUGP("entry %s, mode 0%03o; %sfound, may %screate", path, mode,
00163 sts ? "" : "not ",
00164 may_create ? "" : "not ");
00165
00166
00167 if (sts)
00168 {
00169 if (has_existed) *has_existed=EEXIST;
00170
00171 if (!url__current_has_precedence(sts->url))
00172 goto no_change;
00173
00174
00175
00176
00177
00178 if (sts->remote_status & FS_REMOVED)
00179 {
00180 STOPIF( ops__make_shadow_entry(sts, SHADOWED_BY_REMOTE), NULL);
00181 overwrite=1;
00182 }
00183 }
00184 else
00185 {
00186 STOPIF_CODE_ERR(!may_create, ENOENT, NULL);
00187
00188 STOPIF( ops__allocate(1, &sts, NULL), NULL);
00189 memset(sts, 0, sizeof(*sts));
00190
00191
00192
00193
00194
00195
00196 STOPIF( hlp__strdup(&sts->name, filename), NULL);
00197
00198 sts->remote_status = FS_NEW;
00199 overwrite=1;
00200
00201 STOPIF( ops__new_entries(dir, 1, &sts), NULL);
00202
00203
00204 dir->remote_status |= FS_CHANGED;
00205
00206 if (has_existed) *has_existed=0;
00207 }
00208
00209
00210 if (overwrite)
00211 {
00212 sts->parent=dir;
00213
00214
00215
00216
00217 sts->entry_count=0;
00218 sts->by_inode=NULL;
00219 sts->by_name=NULL;
00220 sts->strings=NULL;
00221
00222 sts->decoder=NULL;
00223 sts->has_orig_md5=0;
00224 memset(& sts->md5, 0, sizeof(sts->md5));
00225
00226 memset(& sts->st, 0, sizeof(sts->st));
00227
00228
00229
00230
00231 if (!(mode & 0777))
00232 mode |= S_ISDIR(mode) ? 0700 : 0600;
00233
00234 sts->st.mode = mode;
00235
00236
00237 time( & sts->st.mtim.tv_sec );
00238
00239
00240 sts->st.uid=getuid();
00241 sts->st.gid=getgid();
00242 }
00243
00244 sts->url=current_url;
00245 ops__mark_parent_cc(sts, remote_status);
00246
00247
00248 sts->new_rev_mode_packed = mode ?
00249 MODE_T_to_PACKED(mode) : sts->old_rev_mode_packed;
00250
00251
00252 if (sts->local_mode_packed == S_IFUNDEF)
00253 {
00254
00255
00256 status=hlp__lstat(path, &st);
00257 if (status == ENOENT)
00258 {
00259
00260
00261 }
00262 else if (!status || status == -ENOENT)
00263 {
00264
00265 sts->local_mode_packed=MODE_T_to_PACKED(st.mode);
00266 }
00267 else
00268 {
00269
00270
00271
00272 }
00273
00274 status=0;
00275 }
00276
00277 DEBUGP("%s is locally a %s",
00278 path, st__type_string(PACKED_to_MODE_T(sts->local_mode_packed)));
00279
00280
00281 no_change:
00282
00283
00284 *new = sts;
00285
00286 ex:
00287 return status;
00288 }
00289
00290
00291 inline int cb___store_prop(struct estat *sts,
00292 const char *utf8_name, const svn_string_t *value,
00293 apr_pool_t *pool)
00294 {
00295 int status;
00296 int user_prop;
00297 apr_pool_t *u_p_pool;
00298 char *copy;
00299 #ifdef DEBUG
00300 static long u_p_count=0,
00301 u_p_bytes=0;
00302 #endif
00303
00304
00305 status=0;
00306 if (!url__current_has_precedence(sts->url)) goto ex;
00307
00308
00309 user_prop=0;
00310 STOPIF( up__parse_prop(sts, utf8_name, value, &user_prop, pool), NULL);
00311 ops__mark_parent_cc(sts, remote_status);
00312 DEBUGP("have name=%s; user? %d", utf8_name, user_prop);
00313
00314
00315 if (action->keep_user_prop && user_prop)
00316 {
00317 if (!sts->user_prop)
00318 {
00319
00320
00321 STOPIF( apr_pool_create(&u_p_pool, sts->url ?
00322 sts->url->pool : global_pool), NULL);
00323
00324 sts->user_prop=apr_hash_make(u_p_pool);
00325 apr_hash_set(sts->user_prop, "", 0, u_p_pool);
00326 }
00327 else
00328 u_p_pool=apr_hash_get(sts->user_prop, "", 0);
00329
00330
00331
00332
00333
00334 copy=apr_palloc(u_p_pool, strlen(utf8_name)+1);
00335 strcpy(copy, utf8_name);
00336 apr_hash_set(sts->user_prop, copy, APR_HASH_KEY_STRING,
00337 svn_string_dup(value, u_p_pool) );
00338
00339 #ifdef ENABLE_DEBUG
00340 u_p_count++;
00341 u_p_bytes += value->len + sizeof(char*) + sizeof(*value);
00342 DEBUGP("%lu user-props stored, with %lu bytes.",
00343 u_p_count, u_p_bytes);
00344 #endif
00345 }
00346
00347 ex:
00348 return status;
00349 }
00350
00351
00352 svn_error_t *cb___set_target_revision(void *edit_baton,
00353 svn_revnum_t rev,
00354 apr_pool_t *pool)
00355 {
00356 int status;
00357 struct estat *root UNUSED=edit_baton;
00358
00359 status=0;
00360 DEBUGP("setting revision to %llu", (t_ull)rev);
00361 cb___dest_rev=rev;
00362 RETURN_SVNERR(status);
00363 }
00364
00365
00366 svn_error_t *cb___open_root(void *edit_baton,
00367 svn_revnum_t base_revision,
00368 apr_pool_t *dir_pool UNUSED,
00369 void **root_baton)
00370 {
00371 struct estat *sts=edit_baton;
00372
00373 *root_baton=sts;
00374
00375 return SVN_NO_ERROR;
00376 }
00377
00378
00379 svn_error_t *cb___delete_entry(const char *utf8_path,
00380 svn_revnum_t revision UNUSED,
00381 void *parent_baton,
00382 apr_pool_t *pool)
00383 {
00384 int status;
00385 struct estat *dir=parent_baton;
00386 struct estat *sts;
00387 char* path;
00388 int chg;
00389
00390 STOPIF( hlp__utf82local(utf8_path, &path, -1), NULL );
00391
00392 STOPIF( ops__find_entry_byname(dir, path, &sts, 0), NULL);
00393
00394 if (sts)
00395 {
00396 DEBUGP("deleting entry %s", path);
00397
00398 ops__mark_parent_cc(sts, remote_status);
00399 STOPIF( cb__remove_from_url(sts, current_url, &chg), NULL);
00400 }
00401 else
00402 {
00403 DEBUGP("entry %s not found!", path);
00405 }
00406
00407 ex:
00408 RETURN_SVNERR(status);
00409 }
00410
00411
00412 svn_error_t *cb___add_directory(const char *utf8_path,
00413 void *parent_baton,
00414 const char *utf8_copy_path,
00415 svn_revnum_t copy_rev,
00416 apr_pool_t *dir_pool,
00417 void **child_baton)
00418 {
00419 struct estat *dir=parent_baton;
00420 struct estat *sts;
00421 int status;
00422 int has_existed;
00423
00424 STOPIF( cb__add_entry(dir, utf8_path, NULL, utf8_copy_path,
00425 copy_rev, S_IFDIR, &has_existed, 1,
00426 child_baton), NULL );
00427 sts=*child_baton;
00428
00429 if (!has_existed)
00430 {
00431
00432
00433
00434 sts->entry_count=0;
00435 sts->by_inode = sts->by_name = NULL;
00436 sts->strings = NULL;
00437 sts->other_revs=sts->to_be_sorted=0;
00438 }
00439
00440 ex:
00441 RETURN_SVNERR(status);
00442 }
00443
00444
00445 svn_error_t *cb___open_directory(const char *utf8_path,
00446 void *parent_baton,
00447 svn_revnum_t base_revision UNUSED,
00448 apr_pool_t *dir_pool,
00449 void **child_baton)
00450 {
00451 struct estat *dir=parent_baton;
00452 int status;
00453
00455 STOPIF( cb__add_entry(dir, utf8_path, NULL, NULL, 0,
00456 S_IFDIR, NULL, 0, child_baton), NULL);
00457
00458 ex:
00459 RETURN_SVNERR(status);
00460 }
00461
00462
00463 svn_error_t *cb___change_dir_prop(void *dir_baton,
00464 const char *utf8_name,
00465 const svn_string_t *value,
00466 apr_pool_t *pool)
00467 {
00468 int status;
00469
00470
00471 STOPIF( cb___store_prop(dir_baton, utf8_name, value, pool), NULL);
00472
00473 ex:
00474 RETURN_SVNERR(status);
00475 }
00476
00477
00478 int cb___close(struct estat *sts)
00479 {
00480 int status;
00481
00482 status=0;
00483 sts->repos_rev = cb___dest_rev;
00484
00485 if (action->repos_feedback)
00486 STOPIF( action->repos_feedback(sts), NULL);
00487
00488 ex:
00489 return status;
00490 }
00491
00492
00493 svn_error_t *cb___close_directory(
00494 void *dir_baton,
00495 apr_pool_t *pool)
00496 {
00497 struct estat *sts=dir_baton;
00498 int status;
00499
00500
00501
00502 IF_FREE(sts->by_name);
00503
00504 STOPIF( cb___close(sts), NULL);
00505
00506 ex:
00507 RETURN_SVNERR(status);
00508 }
00509
00510
00512 svn_error_t *cb___absent_directory(const char *utf8_path,
00513 void *parent_baton,
00514 apr_pool_t *pool)
00515 {
00516 struct estat *dir UNUSED =parent_baton;
00517
00518 DEBUGP("in %s", __PRETTY_FUNCTION__);
00519
00520 return SVN_NO_ERROR;
00521 }
00522
00523
00524 svn_error_t *cb___add_file(const char *utf8_path,
00525 void *parent_baton,
00526 const char *utf8_copy_path,
00527 svn_revnum_t copy_rev,
00528 apr_pool_t *file_pool,
00529 void **file_baton)
00530 {
00531 struct estat *dir=parent_baton;
00532 struct estat *sts;
00533 int status;
00534
00535
00536
00537 STOPIF( cb__add_entry(dir, utf8_path, NULL, utf8_copy_path,
00538 copy_rev, S_IFREG, NULL, 1, file_baton),
00539 NULL);
00540 sts=*file_baton;
00541
00542 ex:
00543 RETURN_SVNERR(status);
00544 }
00545
00546
00547 svn_error_t *cb___open_file(const char *utf8_path,
00548 void *parent_baton,
00549 svn_revnum_t base_revision,
00550 apr_pool_t *file_pool,
00551 void **file_baton)
00552 {
00553 struct estat *dir=parent_baton;
00554 struct estat *sts;
00555 int status;
00556 int was_there;
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 STOPIF( cb__add_entry(dir, utf8_path, NULL, NULL, 0,
00567 0, &was_there, 0, file_baton), NULL);
00568 sts=(struct estat*)*file_baton;
00569
00570
00571
00572 if (was_there)
00573 STOPIF( up__fetch_decoder(sts), NULL);
00574 sts->decoder_is_correct=1;
00575
00576 ex:
00577 RETURN_SVNERR(status);
00578 }
00579
00580
00581 svn_error_t *cb___apply_textdelta(void *file_baton,
00582 const char *base_checksum UNUSED,
00583 apr_pool_t *pool UNUSED,
00584 svn_txdelta_window_handler_t *handler,
00585 void **handler_baton)
00586 {
00587 struct estat *sts UNUSED=file_baton;
00588 int status;
00589
00590 status=0;
00591 if (url__current_has_precedence(sts->url))
00592 ops__mark_changed_parentcc(sts, remote_status);
00593
00594 *handler = cb__txdelta_discard;
00595 *handler_baton=sts;
00596
00597 RETURN_SVNERR(status);
00598 }
00599
00600
00601 svn_error_t *cb___change_file_prop(void *file_baton,
00602 const char *utf8_name,
00603 const svn_string_t *value,
00604 apr_pool_t *pool)
00605 {
00606 int status;
00607
00608
00609 STOPIF( cb___store_prop(file_baton, utf8_name, value, pool), NULL);
00610
00611 ex:
00612 RETURN_SVNERR(status);
00613 }
00614
00615
00616 svn_error_t *cb___close_file(void *file_baton,
00617 const char *text_checksum,
00618 apr_pool_t *pool)
00619 {
00620 struct estat *sts=file_baton;
00621 int status;
00622
00623
00624 STOPIF( cb___close(sts), NULL);
00625
00626 if (!S_ISDIR(sts->st.mode))
00627 {
00628 if (sts->has_orig_md5 || sts->decoder)
00629 DEBUGP("Has an original MD5, %s not used", text_checksum);
00630 else
00631 if (text_checksum)
00632 STOPIF( cs__char2md5(text_checksum, NULL, sts->md5 ), NULL);
00633 }
00634
00635 ex:
00636 RETURN_SVNERR(status);
00637 }
00638
00639
00641 svn_error_t *cb___absent_file(const char *utf8_path,
00642 void *parent_baton,
00643 apr_pool_t *pool)
00644 {
00645 struct estat *dir UNUSED=parent_baton;
00646
00647 DEBUGP("in %s", __PRETTY_FUNCTION__);
00648 return SVN_NO_ERROR;
00649 }
00650
00651
00652 svn_error_t *cb___close_edit(void *edit_baton,
00653 apr_pool_t *pool UNUSED)
00654 {
00655 int status;
00656 struct estat *root UNUSED=edit_baton;
00657
00658 status=0;
00659
00660
00661
00662 RETURN_SVNERR(status);
00663 }
00664
00665
00667 svn_error_t *cb___abort_edit(void *edit_baton,
00668 apr_pool_t *pool UNUSED)
00669 {
00670 struct estat *sts UNUSED=edit_baton;
00671
00672 return SVN_NO_ERROR;
00673 }
00674
00675
00676
00677
00678 const svn_delta_editor_t cb___change_recorder =
00679 {
00680 .set_target_revision = cb___set_target_revision,
00681
00682 .open_root = cb___open_root,
00683
00684 .delete_entry = cb___delete_entry,
00685 .add_directory = cb___add_directory,
00686 .open_directory = cb___open_directory,
00687 .change_dir_prop = cb___change_dir_prop,
00688 .close_directory = cb___close_directory,
00689 .absent_directory = cb___absent_directory,
00690
00691 .add_file = cb___add_file,
00692 .open_file = cb___open_file,
00693 .apply_textdelta = cb___apply_textdelta,
00694 .change_file_prop = cb___change_file_prop,
00695 .close_file = cb___close_file,
00696 .absent_file = cb___absent_file,
00697
00698 .close_edit = cb___close_edit,
00699 .abort_edit = cb___abort_edit,
00700 };
00701
00705 int cb___report_path_rev(struct estat *dir,
00706 const svn_ra_reporter2_t *reporter,
00707 void *report_baton,
00708 apr_pool_t *pool)
00709 {
00710 int status, i;
00711 struct estat *sts;
00712 svn_error_t *status_svn;
00713 char *fn;
00714
00715
00716 status=0;
00717 for(i=0; i<dir->entry_count; i++)
00718 {
00719 sts=dir->by_inode[i];
00720
00721 STOPIF( ops__build_path(&fn, sts), NULL );
00722
00723
00724
00725
00726
00727 if ( sts->repos_rev != sts->parent->repos_rev)
00728 {
00729 DEBUGP("reporting %s at %llu", fn, (t_ull)sts->repos_rev);
00730 STOPIF_SVNERR( reporter->set_path,
00731 (report_baton, fn+2, sts->repos_rev, 0, "", pool));
00732 }
00733
00734 if (S_ISDIR(sts->st.mode) && sts->other_revs)
00735 {
00736 STOPIF( cb___report_path_rev(sts, reporter, report_baton, pool),
00737 NULL);
00738 }
00739 }
00740
00741 ex:
00742 return status;
00743 }
00744
00750 int cb___remover(struct estat *sts, struct url_t *to_remove,
00751 struct url_t **hp, int *has_changes)
00752 {
00753 int status;
00754 struct estat **list;
00755 struct url_t *hp_url;
00756 int child_changes;
00757
00758 status=0;
00759 DEBUGP("clean tree %s url %s", sts->name, to_remove->name);
00760 if (ops__has_children(sts))
00761 {
00762 hp_url=NULL;
00763 child_changes=0;
00764 list=sts->by_inode;
00765
00766 while (*list)
00767 {
00768 STOPIF( cb___remover(*list, to_remove, &hp_url, &child_changes), NULL);
00769 list++;
00770 }
00771
00772 if (sts->parent && hp_url)
00773 {
00774
00775
00776 BUG_ON(sts->url != to_remove && url__sorter(hp_url, sts->url) < 0);
00777
00778 sts->url=hp_url;
00779 }
00780 }
00781
00782 if (!sts->parent)
00783 {
00784 }
00785 else
00786 {
00787 DEBUGP("entry %s has url %s", sts->name, sts->url->name);
00788
00789 if (sts->url == to_remove)
00790 {
00791 DEBUGP("really removing");
00792 sts->remote_status=FS_REMOVED;
00793 ops__mark_changed_parentcc(sts, remote_status);
00794
00795 *has_changes=1;
00796 if (action->repos_feedback)
00797 STOPIF( action->repos_feedback(sts), NULL);
00798 }
00799 else
00800 {
00801 if (!*hp)
00802 *hp=sts->url;
00803 else
00804 if (url__sorter(sts->url, *hp) < 0) *hp=sts->url;
00805 DEBUGP("New hp %s", (*hp)->name);
00806 }
00807 }
00808
00809 if (child_changes)
00810 sts->remote_status |= FS_CHILD_CHANGED;
00811
00812 ex:
00813 return status;
00814 }
00815
00816
00825 int cb__remove_from_url(struct estat *root, struct url_t *to_remove,
00826 int *was_changed)
00827 {
00828 struct url_t *nevermind;
00829 int status;
00830
00831 *was_changed=0;
00832 STOPIF( cb___remover(root, to_remove, &nevermind, was_changed), NULL);
00833 to_remove->current_rev=0;
00834
00835 ex:
00836 return status;
00837 }
00838
00839
00841 int cb__remove_url(struct estat *root, struct url_t *to_remove)
00842 {
00843 int status;
00844 struct url_t *nevermind;
00845 int vvoid;
00846
00847 STOPIF( cb___remover(root, to_remove, &nevermind, &vvoid), NULL);
00848 to_remove->current_rev=0;
00849 url__must_write_defs=1;
00850
00851 ex:
00852 return status;
00853 }
00854
00855
00859 int cb__record_changes(struct estat *root,
00860 svn_revnum_t target,
00861 apr_pool_t *pool)
00862 {
00863 int status;
00864
00865 STOPIF( cb__record_changes_mixed(root, target,
00866 NULL, 0, pool), NULL);
00867 ex:
00868 return status;
00869 }
00870
00871
00905 int cb__record_changes_mixed(struct estat *root,
00906 svn_revnum_t target,
00907 char *other_paths[], svn_revnum_t other_revs,
00908 apr_pool_t *pool)
00909 {
00910 int status;
00911 svn_error_t *status_svn;
00912 void *report_baton;
00913 const svn_ra_reporter2_t *reporter;
00914 int sent_wcroot;
00915 char *cur, **op;
00916
00917
00918 status=0;
00919 cb___dest_rev=target;
00920 STOPIF_SVNERR( svn_ra_do_status,
00921 (current_url->session,
00922 &reporter,
00923 &report_baton,
00924 "",
00925 target,
00926 TRUE,
00927 &cb___change_recorder,
00928 root,
00929 pool) );
00930
00931 sent_wcroot=0;
00932 cur=NULL;
00933 op=NULL;
00934 if (other_paths)
00935 {
00936 op=other_paths;
00937 while ( (cur=*op) )
00938 {
00939 if (cur[0] == '.' && cur[1] == 0)
00940 break;
00941 op++;
00942 }
00943 }
00944
00945
00946
00947
00948 if (cur)
00949 STOPIF_SVNERR( reporter->set_path,
00950 (report_baton,
00951 "", other_revs,
00952 FALSE, NULL, pool));
00953 else if (current_url->current_rev == 0)
00954 STOPIF_SVNERR( reporter->set_path,
00955 (report_baton,
00956 "", target,
00957 TRUE, NULL, pool));
00958 else
00959 STOPIF_SVNERR( reporter->set_path,
00960 (report_baton,
00961 "", current_url->current_rev,
00962 FALSE, NULL, pool));
00963
00964 if (other_paths)
00965 {
00966
00967
00968
00969
00970
00971 while ( (cur=*other_paths) )
00972 {
00973
00974 if (op != other_paths)
00975 {
00976 DEBUGP("reporting %s@%llu", cur, (t_ull)other_revs);
00977
00978 if (cur[0] == '.' && cur[1] == PATH_SEPARATOR)
00979 cur+=2;
00980
00981 STOPIF_SVNERR( reporter->set_path,
00982 (report_baton, cur, other_revs, FALSE, NULL, pool));
00983 }
00984
00985 other_paths++;
00986 }
00987 }
00988
00989
00990 DEBUGP("Getting changes from %llu to %llu",
00991 (t_ull)current_url->current_rev,
00992 (t_ull)target);
00993 #if 0
00994 STOPIF( cb___report_path_rev( root, reporter, report_baton, pool), NULL);
00995 #endif
00996
00997 STOPIF_SVNERR( reporter->finish_report,
00998 (report_baton, global_pool));
00999
01000 current_url->current_rev=cb___dest_rev;
01001
01002 ex:
01003 return status;
01004 }
01005
01006
01010 int cb__does_path_exist(svn_ra_session_t *session,
01011 char *path, svn_revnum_t rev,
01012 int *exists,
01013 apr_pool_t *pool)
01014 {
01015 int status;
01016 svn_dirent_t *dirent;
01017 svn_error_t *status_svn;
01018
01019
01020 status=0;
01021
01022 STOPIF_SVNERR( svn_ra_stat,
01023 (session, path, rev, &dirent, pool));
01024 *exists = dirent != NULL;
01025
01026 ex:
01027 return status;
01028 }
01029