static svn_error_t * copy_foreign_dir(svn_ra_session_t *ra_session, svn_client__pathrev_t *location, svn_wc_context_t *wc_ctx, const char *dst_abspath, svn_depth_t depth, svn_wc_notify_func2_t notify_func, void *notify_baton, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool) { struct edit_baton_t eb; svn_delta_editor_t *editor = svn_delta_default_editor(scratch_pool); const svn_delta_editor_t *wrapped_editor; void *wrapped_baton; const svn_ra_reporter3_t *reporter; void *reporter_baton; eb.pool = scratch_pool; eb.anchor_abspath = dst_abspath; eb.wc_ctx = wc_ctx; eb.notify_func = notify_func; eb.notify_baton = notify_baton; editor->open_root = edit_open; editor->close_edit = edit_close; editor->add_directory = dir_add; editor->change_dir_prop = dir_change_prop; editor->close_directory = dir_close; editor->add_file = file_add; editor->change_file_prop = file_change_prop; editor->apply_textdelta = file_textdelta; editor->close_file = file_close; SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton, editor, &eb, &wrapped_editor, &wrapped_baton, scratch_pool)); SVN_ERR(svn_ra_do_update3(ra_session, &reporter, &reporter_baton, location->rev, "", svn_depth_infinity, FALSE, FALSE, wrapped_editor, wrapped_baton, scratch_pool, scratch_pool)); SVN_ERR(reporter->set_path(reporter_baton, "", location->rev, depth, TRUE /* incomplete */, NULL, scratch_pool)); SVN_ERR(reporter->finish_report(reporter_baton, scratch_pool)); return SVN_NO_ERROR; }
/* Create a repository diff summarize editor and baton. */ svn_error_t * svn_client__get_diff_summarize_editor(const char *target, svn_client_diff_summarize_func_t summarize_func, void *summarize_baton, svn_ra_session_t *ra_session, svn_revnum_t revision, svn_cancel_func_t cancel_func, void *cancel_baton, const svn_delta_editor_t **editor, void **edit_baton, apr_pool_t *pool) { svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool); struct edit_baton *eb = apr_palloc(pool, sizeof(*eb)); eb->target = target; eb->summarize_func = summarize_func; eb->summarize_func_baton = summarize_baton; eb->ra_session = ra_session; eb->revision = revision; eb->walk_deleted_repos_dirs = TRUE; eb->cancel_func = cancel_func; eb->cancel_baton = cancel_baton; tree_editor->open_root = open_root; tree_editor->delete_entry = delete_entry; tree_editor->add_directory = add_directory; tree_editor->open_directory = open_directory; tree_editor->change_dir_prop = change_prop; tree_editor->close_directory = close_directory; tree_editor->add_file = add_file; tree_editor->open_file = open_file; tree_editor->apply_textdelta = apply_textdelta; tree_editor->change_file_prop = change_prop; tree_editor->close_file = close_file; return svn_delta_get_cancellation_editor(cancel_func, cancel_baton, tree_editor, eb, editor, edit_baton, pool); }
static svn_error_t * bench_null_export(svn_revnum_t *result_rev, const char *from_path_or_url, svn_opt_revision_t *peg_revision, svn_opt_revision_t *revision, svn_depth_t depth, void *baton, svn_client_ctx_t *ctx, svn_boolean_t quiet, apr_pool_t *pool) { svn_revnum_t edit_revision = SVN_INVALID_REVNUM; svn_boolean_t from_is_url = svn_path_is_url(from_path_or_url); SVN_ERR_ASSERT(peg_revision != NULL); SVN_ERR_ASSERT(revision != NULL); if (peg_revision->kind == svn_opt_revision_unspecified) peg_revision->kind = svn_path_is_url(from_path_or_url) ? svn_opt_revision_head : svn_opt_revision_working; if (revision->kind == svn_opt_revision_unspecified) revision = peg_revision; if (from_is_url || ! SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind)) { svn_client__pathrev_t *loc; svn_ra_session_t *ra_session; svn_node_kind_t kind; /* Get the RA connection. */ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc, from_path_or_url, NULL, peg_revision, revision, ctx, pool)); SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, pool)); if (kind == svn_node_file) { apr_hash_t *props; /* Since you cannot actually root an editor at a file, we * manually drive a few functions of our editor. */ /* Step outside the editor-likeness for a moment, to actually talk * to the repository. */ /* ### note: the stream will not be closed */ SVN_ERR(svn_ra_get_file(ra_session, "", loc->rev, svn_stream_empty(pool), NULL, &props, pool)); } else if (kind == svn_node_dir) { void *edit_baton = NULL; const svn_delta_editor_t *export_editor = NULL; const svn_ra_reporter3_t *reporter; void *report_baton; svn_delta_editor_t *editor = svn_delta_default_editor(pool); editor->set_target_revision = set_target_revision; editor->open_root = open_root; editor->add_directory = add_directory; editor->add_file = add_file; editor->apply_textdelta = apply_textdelta; editor->close_file = close_file; editor->change_file_prop = change_file_prop; editor->change_dir_prop = change_dir_prop; /* for ra_svn, we don't need an editior in quiet mode */ if (!quiet || strncmp(loc->repos_root_url, "svn:", 4)) SVN_ERR(svn_delta_get_cancellation_editor(ctx->cancel_func, ctx->cancel_baton, editor, baton, &export_editor, &edit_baton, pool)); /* Manufacture a basic 'report' to the update reporter. */ SVN_ERR(svn_ra_do_update3(ra_session, &reporter, &report_baton, loc->rev, "", /* no sub-target */ depth, FALSE, /* don't want copyfrom-args */ FALSE, /* don't want ignore_ancestry */ export_editor, edit_baton, pool, pool)); SVN_ERR(reporter->set_path(report_baton, "", loc->rev, /* Depth is irrelevant, as we're passing start_empty=TRUE anyway. */ svn_depth_infinity, TRUE, /* "help, my dir is empty!" */ NULL, pool)); SVN_ERR(reporter->finish_report(report_baton, pool)); } else if (kind == svn_node_none) { return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL, _("URL '%s' doesn't exist"), from_path_or_url); } /* kind == svn_node_unknown not handled */ } if (result_rev) *result_rev = edit_revision; return SVN_NO_ERROR; }
svn_error_t * svn_repos_verify_fs2(svn_repos_t *repos, svn_revnum_t start_rev, svn_revnum_t end_rev, svn_repos_notify_func_t notify_func, void *notify_baton, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *pool) { svn_fs_t *fs = svn_repos_fs(repos); svn_revnum_t youngest; svn_revnum_t rev; apr_pool_t *iterpool = svn_pool_create(pool); svn_repos_notify_t *notify; /* Determine the current youngest revision of the filesystem. */ SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool)); /* Use default vals if necessary. */ if (! SVN_IS_VALID_REVNUM(start_rev)) start_rev = 0; if (! SVN_IS_VALID_REVNUM(end_rev)) end_rev = youngest; /* Validate the revisions. */ if (start_rev > end_rev) return svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, NULL, _("Start revision %ld" " is greater than end revision %ld"), start_rev, end_rev); if (end_rev > youngest) return svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, NULL, _("End revision %ld is invalid " "(youngest revision is %ld)"), end_rev, youngest); /* Create a notify object that we can reuse within the loop. */ if (notify_func) notify = svn_repos_notify_create(svn_repos_notify_verify_rev_end, pool); for (rev = start_rev; rev <= end_rev; rev++) { svn_delta_editor_t *dump_editor; void *dump_edit_baton; const svn_delta_editor_t *cancel_editor; void *cancel_edit_baton; svn_fs_root_t *to_root; apr_hash_t *props; svn_pool_clear(iterpool); /* Get cancellable dump editor, but with our close_directory handler. */ SVN_ERR(get_dump_editor((const svn_delta_editor_t **)&dump_editor, &dump_edit_baton, fs, rev, "", svn_stream_empty(pool), notify_func, notify_baton, start_rev, FALSE, TRUE, /* use_deltas, verify */ iterpool)); dump_editor->close_directory = verify_close_directory; SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton, dump_editor, dump_edit_baton, &cancel_editor, &cancel_edit_baton, iterpool)); SVN_ERR(svn_fs_revision_root(&to_root, fs, rev, iterpool)); SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE, cancel_editor, cancel_edit_baton, NULL, NULL, iterpool)); SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, iterpool)); if (notify_func) { notify->revision = rev; notify_func(notify_baton, notify, iterpool); } } /* We're done. */ if (notify_func) { notify = svn_repos_notify_create(svn_repos_notify_verify_end, iterpool); notify_func(notify_baton, notify, iterpool); } svn_pool_destroy(iterpool); return SVN_NO_ERROR; }
static svn_error_t * make_reporter(svn_ra_session_t *session, const svn_ra_reporter3_t **reporter, void **report_baton, svn_revnum_t revision, const char *target, const char *other_url, svn_boolean_t text_deltas, svn_depth_t depth, svn_boolean_t send_copyfrom_args, svn_boolean_t ignore_ancestry, const svn_delta_editor_t *editor, void *edit_baton, apr_pool_t *pool) { svn_ra_local__session_baton_t *sess = session->priv; void *rbaton; int repos_url_len; const char *other_fs_path = NULL; const char *repos_url_decoded; /* Get the HEAD revision if one is not supplied. */ if (! SVN_IS_VALID_REVNUM(revision)) SVN_ERR(svn_fs_youngest_rev(&revision, sess->fs, pool)); /* If OTHER_URL was provided, validate it and convert it into a regular filesystem path. */ if (other_url) { other_url = svn_path_uri_decode(other_url, pool); repos_url_decoded = svn_path_uri_decode(sess->repos_url, pool); repos_url_len = strlen(repos_url_decoded); /* Sanity check: the other_url better be in the same repository as the original session url! */ if (strncmp(other_url, repos_url_decoded, repos_url_len) != 0) return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, _("'%s'\n" "is not the same repository as\n" "'%s'"), other_url, sess->repos_url); other_fs_path = other_url + repos_url_len; } /* Pass back our reporter */ *reporter = &ra_local_reporter; SVN_ERR(get_username(session, pool)); if (sess->callbacks) SVN_ERR(svn_delta_get_cancellation_editor(sess->callbacks->cancel_func, sess->callback_baton, editor, edit_baton, &editor, &edit_baton, pool)); /* Build a reporter baton. */ SVN_ERR(svn_repos_begin_report2(&rbaton, revision, sess->repos, sess->fs_path->data, target, other_fs_path, text_deltas, depth, ignore_ancestry, send_copyfrom_args, editor, edit_baton, NULL, NULL, pool)); /* Wrap the report baton given us by the repos layer with our own reporter baton. */ *report_baton = make_reporter_baton(sess, rbaton, pool); return SVN_NO_ERROR; }
/* Create a repository diff editor and baton. */ svn_error_t * svn_client__get_diff_editor(const svn_delta_editor_t **editor, void **edit_baton, svn_depth_t depth, svn_ra_session_t *ra_session, svn_revnum_t revision, svn_boolean_t walk_deleted_dirs, svn_boolean_t text_deltas, const svn_wc_diff_callbacks4_t *diff_callbacks, void *diff_cmd_baton, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, void *notify_baton, apr_pool_t *result_pool) { apr_pool_t *editor_pool = svn_pool_create(result_pool); svn_delta_editor_t *tree_editor = svn_delta_default_editor(editor_pool); struct edit_baton *eb = apr_pcalloc(editor_pool, sizeof(*eb)); svn_delta_shim_callbacks_t *shim_callbacks = svn_delta_shim_callbacks_default(editor_pool); eb->pool = editor_pool; eb->depth = depth; eb->diff_callbacks = diff_callbacks; eb->diff_cmd_baton = diff_cmd_baton; eb->ra_session = ra_session; eb->revision = revision; eb->empty_file = NULL; eb->empty_hash = apr_hash_make(eb->pool); eb->deleted_paths = apr_hash_make(eb->pool); eb->notify_func = notify_func; eb->notify_baton = notify_baton; eb->walk_deleted_repos_dirs = walk_deleted_dirs; eb->text_deltas = text_deltas; eb->cancel_func = cancel_func; eb->cancel_baton = cancel_baton; tree_editor->set_target_revision = set_target_revision; tree_editor->open_root = open_root; tree_editor->delete_entry = delete_entry; tree_editor->add_directory = add_directory; tree_editor->open_directory = open_directory; tree_editor->add_file = add_file; tree_editor->open_file = open_file; tree_editor->apply_textdelta = apply_textdelta; tree_editor->close_file = close_file; tree_editor->close_directory = close_directory; tree_editor->change_file_prop = change_file_prop; tree_editor->change_dir_prop = change_dir_prop; tree_editor->close_edit = close_edit; tree_editor->absent_directory = absent_directory; tree_editor->absent_file = absent_file; SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton, tree_editor, eb, editor, edit_baton, eb->pool)); shim_callbacks->fetch_kind_func = fetch_kind_func; shim_callbacks->fetch_props_func = fetch_props_func; shim_callbacks->fetch_base_func = fetch_base_func; shim_callbacks->fetch_baton = eb; SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton, shim_callbacks, result_pool, result_pool)); return SVN_NO_ERROR; }