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; }
/* Note: this implementation is very similar to svn_client_proplist. */ svn_error_t * svn_client_propget4(apr_hash_t **props, const char *propname, const char *target, const svn_opt_revision_t *peg_revision, const svn_opt_revision_t *revision, svn_revnum_t *actual_revnum, svn_depth_t depth, const apr_array_header_t *changelists, svn_client_ctx_t *ctx, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { svn_revnum_t revnum; SVN_ERR(error_if_wcprop_name(propname)); if (!svn_path_is_url(target)) SVN_ERR_ASSERT(svn_dirent_is_absolute(target)); peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision, target); revision = svn_cl__rev_default_to_peg(revision, peg_revision); *props = apr_hash_make(result_pool); if (! svn_path_is_url(target) && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind) && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind)) { svn_node_kind_t kind; svn_boolean_t pristine; svn_error_t *err; /* If FALSE, we want the working revision. */ pristine = (revision->kind == svn_opt_revision_committed || revision->kind == svn_opt_revision_base); SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, target, FALSE, scratch_pool)); if (kind == svn_node_unknown || kind == svn_node_none) { /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only for this function. */ return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL, _("'%s' is not under version control"), svn_dirent_local_style(target, scratch_pool)); } err = svn_client__get_revision_number(&revnum, NULL, ctx->wc_ctx, target, NULL, revision, scratch_pool); if (err && err->apr_err == SVN_ERR_CLIENT_BAD_REVISION) { svn_error_clear(err); revnum = SVN_INVALID_REVNUM; } else if (err) return svn_error_trace(err); SVN_ERR(get_prop_from_wc(*props, propname, target, pristine, kind, depth, changelists, ctx, scratch_pool, result_pool)); } else { const char *url; svn_ra_session_t *ra_session; svn_node_kind_t kind; /* Get an RA plugin for this filesystem object. */ SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum, &url, target, NULL, peg_revision, revision, ctx, scratch_pool)); SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, scratch_pool)); SVN_ERR(remote_propget(*props, propname, url, "", kind, revnum, ra_session, depth, result_pool, scratch_pool)); } if (actual_revnum) *actual_revnum = revnum; return SVN_NO_ERROR; }
svn_error_t * svn_client__get_normalized_stream(svn_stream_t **normal_stream, svn_wc_context_t *wc_ctx, const char *local_abspath, const svn_opt_revision_t *revision, svn_boolean_t expand_keywords, svn_boolean_t normalize_eols, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { apr_hash_t *kw = NULL; svn_subst_eol_style_t style; apr_hash_t *props; svn_string_t *eol_style, *keywords, *special; const char *eol = NULL; svn_boolean_t local_mod = FALSE; apr_time_t tm; svn_stream_t *input; svn_node_kind_t kind; SVN_ERR_ASSERT(SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind)); SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, local_abspath, FALSE, scratch_pool)); if (kind == svn_node_unknown || kind == svn_node_none) return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL, _("'%s' is not under version control"), svn_dirent_local_style(local_abspath, scratch_pool)); if (kind != svn_node_file) return svn_error_createf(SVN_ERR_CLIENT_IS_DIRECTORY, NULL, _("'%s' refers to a directory"), svn_dirent_local_style(local_abspath, scratch_pool)); if (revision->kind != svn_opt_revision_working) { SVN_ERR(svn_wc_get_pristine_contents2(&input, wc_ctx, local_abspath, result_pool, scratch_pool)); if (input == NULL) return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL, _("'%s' has no base revision until it is committed"), svn_dirent_local_style(local_abspath, scratch_pool)); SVN_ERR(svn_wc_get_pristine_props(&props, wc_ctx, local_abspath, scratch_pool, scratch_pool)); } else { svn_wc_status3_t *status; SVN_ERR(svn_stream_open_readonly(&input, local_abspath, scratch_pool, result_pool)); SVN_ERR(svn_wc_prop_list2(&props, wc_ctx, local_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_wc_status3(&status, wc_ctx, local_abspath, scratch_pool, scratch_pool)); if (status->text_status != svn_wc_status_normal) local_mod = TRUE; } eol_style = apr_hash_get(props, SVN_PROP_EOL_STYLE, APR_HASH_KEY_STRING); keywords = apr_hash_get(props, SVN_PROP_KEYWORDS, APR_HASH_KEY_STRING); special = apr_hash_get(props, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING); if (eol_style) svn_subst_eol_style_from_value(&style, &eol, eol_style->data); if (local_mod && (! special)) { /* Use the modified time from the working copy if the file */ SVN_ERR(svn_io_file_affected_time(&tm, local_abspath, scratch_pool)); } else { SVN_ERR(svn_wc__node_get_changed_info(NULL, &tm, NULL, wc_ctx, local_abspath, scratch_pool, scratch_pool)); } if (keywords) { svn_revnum_t changed_rev; const char *rev_str; const char *author; const char *url; SVN_ERR(svn_wc__node_get_changed_info(&changed_rev, NULL, &author, wc_ctx, local_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, local_abspath, scratch_pool, scratch_pool)); if (local_mod) { /* For locally modified files, we'll append an 'M' to the revision number, and set the author to "(local)" since we can't always determine the current user's username */ rev_str = apr_psprintf(scratch_pool, "%ldM", changed_rev); author = _("(local)"); } else { rev_str = apr_psprintf(scratch_pool, "%ld", changed_rev); } SVN_ERR(svn_subst_build_keywords2(&kw, keywords->data, rev_str, url, tm, author, scratch_pool)); } /* Wrap the output stream if translation is needed. */ if (eol != NULL || kw != NULL) input = svn_subst_stream_translated( input, (eol_style && normalize_eols) ? SVN_SUBST_NATIVE_EOL_STR : eol, FALSE, kw, expand_keywords, result_pool); *normal_stream = input; return SVN_NO_ERROR; }
svn_error_t * svn_client_proplist3(const char *path_or_url, const svn_opt_revision_t *peg_revision, const svn_opt_revision_t *revision, svn_depth_t depth, const apr_array_header_t *changelists, svn_proplist_receiver_t receiver, void *receiver_baton, svn_client_ctx_t *ctx, apr_pool_t *pool) { const char *url; peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision, path_or_url); revision = svn_cl__rev_default_to_peg(revision, peg_revision); if (depth == svn_depth_unknown) depth = svn_depth_empty; if (! svn_path_is_url(path_or_url) && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind) && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind)) { svn_boolean_t pristine; svn_node_kind_t kind; apr_hash_t *changelist_hash = NULL; const char *local_abspath; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool)); pristine = ((revision->kind == svn_opt_revision_committed) || (revision->kind == svn_opt_revision_base)); SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, local_abspath, FALSE, pool)); if (kind == svn_node_unknown || kind == svn_node_none) { /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only for this function. */ return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL, _("'%s' is not under version control"), svn_dirent_local_style(local_abspath, pool)); } if (changelists && changelists->nelts) SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool)); /* Fetch, recursively or not. */ if (kind == svn_node_dir) { struct recursive_proplist_receiver_baton rb; rb.wc_ctx = ctx->wc_ctx; rb.wrapped_receiver = receiver; rb.wrapped_receiver_baton = receiver_baton; if (strcmp(path_or_url, local_abspath) != 0) { rb.anchor = path_or_url; rb.anchor_abspath = local_abspath; } else { rb.anchor = NULL; rb.anchor_abspath = NULL; } SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, local_abspath, NULL, depth, FALSE, pristine, changelists, recursive_proplist_receiver, &rb, ctx->cancel_func, ctx->cancel_baton, pool)); } else if (svn_wc__changelist_match(ctx->wc_ctx, local_abspath, changelist_hash, pool)) { apr_hash_t *hash; SVN_ERR(pristine_or_working_props(&hash, ctx->wc_ctx, local_abspath, pristine, pool, pool)); SVN_ERR(call_receiver(path_or_url, hash, receiver, receiver_baton, pool)); } } else /* remote target */ { svn_ra_session_t *ra_session; svn_node_kind_t kind; apr_pool_t *subpool = svn_pool_create(pool); svn_revnum_t revnum; /* Get an RA session for this URL. */ SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum, &url, path_or_url, NULL, peg_revision, revision, ctx, pool)); SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool)); SVN_ERR(remote_proplist(url, "", kind, revnum, ra_session, depth, receiver, receiver_baton, pool, subpool)); svn_pool_destroy(subpool); } return SVN_NO_ERROR; }
svn_error_t * svn_client_cat2(svn_stream_t *out, const char *path_or_url, const svn_opt_revision_t *peg_revision, const svn_opt_revision_t *revision, svn_client_ctx_t *ctx, apr_pool_t *pool) { svn_ra_session_t *ra_session; svn_revnum_t rev; svn_string_t *eol_style; svn_string_t *keywords; apr_hash_t *props; const char *url; svn_stream_t *output = out; svn_error_t *err; /* ### Inconsistent default revision logic in this command. */ if (peg_revision->kind == svn_opt_revision_unspecified) { peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision, path_or_url); revision = svn_cl__rev_default_to_head_or_base(revision, path_or_url); } else { peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision, path_or_url); revision = svn_cl__rev_default_to_peg(revision, peg_revision); } if (! svn_path_is_url(path_or_url) && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind) && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind)) { const char *local_abspath; svn_stream_t *normal_stream; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool)); SVN_ERR(svn_client__get_normalized_stream(&normal_stream, ctx->wc_ctx, local_abspath, revision, TRUE, FALSE, ctx->cancel_func, ctx->cancel_baton, pool, pool)); /* We don't promise to close output, so disown it to ensure we don't. */ output = svn_stream_disown(output, pool); return svn_error_trace(svn_stream_copy3(normal_stream, output, ctx->cancel_func, ctx->cancel_baton, pool)); } /* Get an RA plugin for this filesystem object. */ SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev, &url, path_or_url, NULL, peg_revision, revision, ctx, pool)); /* Grab some properties we need to know in order to figure out if anything special needs to be done with this file. */ err = svn_ra_get_file(ra_session, "", rev, NULL, NULL, &props, pool); if (err) { if (err->apr_err == SVN_ERR_FS_NOT_FILE) { return svn_error_createf(SVN_ERR_CLIENT_IS_DIRECTORY, err, _("URL '%s' refers to a directory"), url); } else { return svn_error_trace(err); } } eol_style = apr_hash_get(props, SVN_PROP_EOL_STYLE, APR_HASH_KEY_STRING); keywords = apr_hash_get(props, SVN_PROP_KEYWORDS, APR_HASH_KEY_STRING); if (eol_style || keywords) { /* It's a file with no special eol style or keywords. */ svn_subst_eol_style_t eol; const char *eol_str; apr_hash_t *kw; if (eol_style) svn_subst_eol_style_from_value(&eol, &eol_str, eol_style->data); else { eol = svn_subst_eol_style_none; eol_str = NULL; } if (keywords) { svn_string_t *cmt_rev, *cmt_date, *cmt_author; apr_time_t when = 0; cmt_rev = apr_hash_get(props, SVN_PROP_ENTRY_COMMITTED_REV, APR_HASH_KEY_STRING); cmt_date = apr_hash_get(props, SVN_PROP_ENTRY_COMMITTED_DATE, APR_HASH_KEY_STRING); cmt_author = apr_hash_get(props, SVN_PROP_ENTRY_LAST_AUTHOR, APR_HASH_KEY_STRING); if (cmt_date) SVN_ERR(svn_time_from_cstring(&when, cmt_date->data, pool)); SVN_ERR(svn_subst_build_keywords2 (&kw, keywords->data, cmt_rev->data, url, when, cmt_author ? cmt_author->data : NULL, pool)); } else kw = NULL; /* Interject a translating stream */ output = svn_subst_stream_translated(svn_stream_disown(out, pool), eol_str, FALSE, kw, TRUE, pool); } SVN_ERR(svn_ra_get_file(ra_session, "", rev, output, NULL, NULL, pool)); if (out != output) /* Close the interjected stream */ SVN_ERR(svn_stream_close(output)); return SVN_NO_ERROR; }