📄 ra.c
字号:
/* * ra.c : routines for interacting with the RA layer * * ==================================================================== * Copyright (c) 2000-2004 CollabNet. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals. For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <apr_pools.h>#include <assert.h>#include "svn_error.h"#include "svn_pools.h"#include "svn_string.h"#include "svn_sorts.h"#include "svn_ra.h"#include "svn_wc.h"#include "svn_client.h"#include "svn_path.h"#include "svn_props.h"#include "client.h"#include "svn_private_config.h"static svn_error_t *open_admin_tmp_file(apr_file_t **fp, void *callback_baton, apr_pool_t *pool){ svn_client__callback_baton_t *cb = callback_baton; SVN_ERR(svn_wc_create_tmp_file2(fp, NULL, cb->base_dir, svn_io_file_del_on_close, pool)); return SVN_NO_ERROR;}static svn_error_t *open_tmp_file(apr_file_t **fp, void *callback_baton, apr_pool_t *pool){ svn_client__callback_baton_t *cb = callback_baton; const char *truepath; if (cb->base_dir && ! cb->read_only_wc) truepath = apr_pstrdup(pool, cb->base_dir); else SVN_ERR(svn_io_temp_dir(&truepath, pool)); /* Tack on a made-up filename. */ truepath = svn_path_join(truepath, "tempfile", pool); /* Open a unique file; use APR_DELONCLOSE. */ SVN_ERR(svn_io_open_unique_file2(fp, NULL, truepath, ".tmp", svn_io_file_del_on_close, pool)); return SVN_NO_ERROR;}/* This implements the 'svn_ra_get_wc_prop_func_t' interface. */static svn_error_t *get_wc_prop(void *baton, const char *relpath, const char *name, const svn_string_t **value, apr_pool_t *pool){ svn_client__callback_baton_t *cb = baton; *value = NULL; /* If we have a list of commit_items, search through that for a match for this relative URL. */ if (cb->commit_items) { int i; for (i = 0; i < cb->commit_items->nelts; i++) { svn_client_commit_item2_t *item = APR_ARRAY_IDX(cb->commit_items, i, svn_client_commit_item2_t *); if (! strcmp(relpath, svn_path_uri_decode(item->url, pool))) return svn_wc_prop_get(value, name, item->path, cb->base_access, pool); } return SVN_NO_ERROR; } /* If we don't have a base directory, then there are no properties. */ else if (cb->base_dir == NULL) return SVN_NO_ERROR; return svn_wc_prop_get(value, name, svn_path_join(cb->base_dir, relpath, pool), cb->base_access, pool);}/* This implements the 'svn_ra_push_wc_prop_func_t' interface. */static svn_error_t *push_wc_prop(void *baton, const char *relpath, const char *name, const svn_string_t *value, apr_pool_t *pool){ svn_client__callback_baton_t *cb = baton; int i; /* If we're committing, search through the commit_items list for a match for this relative URL. */ if (! cb->commit_items) return svn_error_createf (SVN_ERR_UNSUPPORTED_FEATURE, NULL, _("Attempt to set wc property '%s' on '%s' in a non-commit operation"), name, svn_path_local_style(relpath, pool)); for (i = 0; i < cb->commit_items->nelts; i++) { svn_client_commit_item2_t *item = APR_ARRAY_IDX(cb->commit_items, i, svn_client_commit_item2_t *); if (strcmp(relpath, svn_path_uri_decode(item->url, pool)) == 0) { apr_pool_t *cpool = item->wcprop_changes->pool; svn_prop_t *prop = apr_palloc(cpool, sizeof(*prop)); prop->name = apr_pstrdup(cpool, name); if (value) { prop->value = svn_string_ncreate(value->data, value->len, cpool); } else prop->value = NULL; /* Buffer the propchange to take effect during the post-commit process. */ *((svn_prop_t **) apr_array_push(item->wcprop_changes)) = prop; return SVN_NO_ERROR; } } return SVN_NO_ERROR;}/* This implements the 'svn_ra_set_wc_prop_func_t' interface. */static svn_error_t *set_wc_prop(void *baton, const char *path, const char *name, const svn_string_t *value, apr_pool_t *pool){ svn_client__callback_baton_t *cb = baton; svn_wc_adm_access_t *adm_access; const svn_wc_entry_t *entry; const char *full_path = svn_path_join(cb->base_dir, path, pool); SVN_ERR(svn_wc_entry(&entry, full_path, cb->base_access, FALSE, pool)); if (! entry) return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL, _("'%s' is not under version control"), svn_path_local_style(full_path, pool)); SVN_ERR(svn_wc_adm_retrieve(&adm_access, cb->base_access, (entry->kind == svn_node_dir ? full_path : svn_path_dirname(full_path, pool)), pool)); /* We pass 1 for the 'force' parameter here. Since the property is coming from the repository, we definitely want to accept it. Ideally, we'd raise a conflict if, say, the received property is svn:eol-style yet the file has a locally added svn:mime-type claiming that it's binary. Probably the repository is still right, but the conflict would remind the user to make sure. Unfortunately, we don't have a clean mechanism for doing that here, so we just set the property and hope for the best. */ return svn_wc_prop_set2(name, value, full_path, adm_access, TRUE, pool);}struct invalidate_wcprop_walk_baton{ /* The wcprop to invalidate. */ const char *prop_name; /* Access baton for the top of the walk. */ svn_wc_adm_access_t *base_access;};/* This implements the `found_entry' prototype in `svn_wc_entry_callbacks_t'. */static svn_error_t *invalidate_wcprop_for_entry(const char *path, const svn_wc_entry_t *entry, void *walk_baton, apr_pool_t *pool){ struct invalidate_wcprop_walk_baton *wb = walk_baton; svn_wc_adm_access_t *entry_access; SVN_ERR(svn_wc_adm_retrieve(&entry_access, wb->base_access, ((entry->kind == svn_node_dir) ? path : svn_path_dirname(path, pool)), pool)); /* It doesn't matter if we pass 0 or 1 for force here, since property deletion is always permitted. */ return svn_wc_prop_set2(wb->prop_name, NULL, path, entry_access, FALSE, pool);}/* This implements the `svn_ra_invalidate_wc_props_func_t' interface. */static svn_error_t *invalidate_wc_props(void *baton, const char *path, const char *prop_name, apr_pool_t *pool){ svn_client__callback_baton_t *cb = baton; svn_wc_entry_callbacks_t walk_callbacks; struct invalidate_wcprop_walk_baton wb; svn_wc_adm_access_t *adm_access; wb.base_access = cb->base_access; wb.prop_name = prop_name; walk_callbacks.found_entry = invalidate_wcprop_for_entry; path = svn_path_join(cb->base_dir, path, pool); SVN_ERR(svn_wc_adm_probe_retrieve(&adm_access, cb->base_access, path, pool)); SVN_ERR(svn_wc_walk_entries2(path, adm_access, &walk_callbacks, &wb, FALSE, cb->ctx->cancel_func, cb->ctx->cancel_baton, pool)); return SVN_NO_ERROR;}svn_error_t * svn_client__open_ra_session_internal(svn_ra_session_t **ra_session, const char *base_url, const char *base_dir, svn_wc_adm_access_t *base_access, apr_array_header_t *commit_items, svn_boolean_t use_admin, svn_boolean_t read_only_wc, svn_client_ctx_t *ctx, apr_pool_t *pool){ svn_ra_callbacks2_t *cbtable = apr_pcalloc(pool, sizeof(*cbtable)); svn_client__callback_baton_t *cb = apr_pcalloc(pool, sizeof(*cb)); cbtable->open_tmp_file = use_admin ? open_admin_tmp_file : open_tmp_file; cbtable->get_wc_prop = use_admin ? get_wc_prop : NULL; cbtable->set_wc_prop = read_only_wc ? NULL : set_wc_prop; cbtable->push_wc_prop = commit_items ? push_wc_prop : NULL; cbtable->invalidate_wc_props = read_only_wc ? NULL : invalidate_wc_props; cbtable->auth_baton = ctx->auth_baton; /* new-style */ cbtable->progress_func = ctx->progress_func; cbtable->progress_baton = ctx->progress_baton; cb->base_dir = base_dir; cb->base_access = base_access; cb->read_only_wc = read_only_wc; cb->pool = pool; cb->commit_items = commit_items; cb->ctx = ctx; SVN_ERR(svn_ra_open2(ra_session, base_url, cbtable, cb, ctx->config, pool)); return SVN_NO_ERROR;}svn_error_t *svn_client_open_ra_session(svn_ra_session_t **session, const char *url, svn_client_ctx_t *ctx, apr_pool_t *pool){ return svn_client__open_ra_session_internal(session, url, NULL, NULL, NULL, FALSE, TRUE, ctx, pool);}svn_error_t *svn_client_uuid_from_url(const char **uuid, const char *url, svn_client_ctx_t *ctx, apr_pool_t *pool){ svn_ra_session_t *ra_session; apr_pool_t *subpool = svn_pool_create(pool);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -