export.c
来自「subversion-1.4.3-1.tar.gz 配置svn的源码」· C语言 代码 · 共 958 行 · 第 1/3 页
C
958 行
/* * export.c: export a tree. * * ==================================================================== * 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/. * ==================================================================== *//* ==================================================================== *//*** Includes. ***/#include <apr_file_io.h>#include <apr_md5.h>#include "svn_types.h"#include "svn_wc.h"#include "svn_client.h"#include "svn_string.h"#include "svn_error.h"#include "svn_path.h"#include "svn_pools.h"#include "svn_subst.h"#include "svn_time.h"#include "svn_md5.h"#include "svn_props.h"#include "client.h"#include "svn_private_config.h"/*** Code. ***//* Add EXTERNALS_PROP_VAL for the export destination path PATH to TRAVERSAL_INFO. */static voidadd_externals(apr_hash_t *externals, const char *path, const svn_string_t *externals_prop_val){ apr_pool_t *pool = apr_hash_pool_get(externals); if (! externals_prop_val) return; apr_hash_set(externals, apr_pstrdup(pool, path), APR_HASH_KEY_STRING, apr_pstrmemdup(pool, externals_prop_val->data, externals_prop_val->len));}/* Helper function that gets the eol style and optionally overrides the EOL marker for files marked as native with the EOL marker matching the string specified in requested_value which is of the same format as the svn:eol-style property values. */static svn_error_t *get_eol_style(svn_subst_eol_style_t *style, const char **eol, const char *value, const char *requested_value){ svn_subst_eol_style_from_value(style, eol, value); if (requested_value && *style == svn_subst_eol_style_native) { svn_subst_eol_style_t requested_style; const char *requested_eol; svn_subst_eol_style_from_value(&requested_style, &requested_eol, requested_value); if (requested_style == svn_subst_eol_style_fixed) *eol = requested_eol; else return svn_error_createf(SVN_ERR_IO_UNKNOWN_EOL, NULL, _("'%s' is not a valid EOL value"), requested_value); } return SVN_NO_ERROR;}static svn_error_t *copy_one_versioned_file(const char *from, const char *to, svn_wc_adm_access_t *adm_access, svn_opt_revision_t *revision, const char *native_eol, apr_pool_t *pool){ const svn_wc_entry_t *entry; apr_hash_t *kw = NULL; svn_subst_eol_style_t style; apr_hash_t *props; const char *base; svn_string_t *eol_style, *keywords, *executable, *externals, *special; const char *eol = NULL; svn_boolean_t local_mod = FALSE; apr_time_t tm; SVN_ERR(svn_wc_entry(&entry, from, adm_access, FALSE, pool)); /* Only export 'added' files when the revision is WORKING. Otherwise, skip the 'added' files, since they didn't exist in the BASE revision and don't have an associated text-base. Don't export 'deleted' files and directories unless it's a revision other than WORKING. These files and directories don't really exist in WORKING. */ if ((revision->kind != svn_opt_revision_working && entry->schedule == svn_wc_schedule_add) || (revision->kind == svn_opt_revision_working && entry->schedule == svn_wc_schedule_delete)) return SVN_NO_ERROR; if (revision->kind != svn_opt_revision_working) { SVN_ERR(svn_wc_get_pristine_copy_path(from, &base, pool)); SVN_ERR(svn_wc_get_prop_diffs(NULL, &props, from, adm_access, pool)); } else { svn_wc_status2_t *status; base = from; SVN_ERR(svn_wc_prop_list(&props, from, adm_access, pool)); SVN_ERR(svn_wc_status2(&status, from, adm_access, 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); executable = apr_hash_get(props, SVN_PROP_EXECUTABLE, APR_HASH_KEY_STRING); externals = apr_hash_get(props, SVN_PROP_EXTERNALS, APR_HASH_KEY_STRING); special = apr_hash_get(props, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING); if (eol_style) SVN_ERR(get_eol_style(&style, &eol, eol_style->data, native_eol)); if (local_mod && (! special)) { /* Use the modified time from the working copy of the file */ SVN_ERR(svn_io_file_affected_time(&tm, from, pool)); } else { tm = entry->cmt_date; } if (keywords) { const char *fmt; const char *author; 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 */ fmt = "%ldM"; author = _("(local)"); } else { fmt = "%ld"; author = entry->cmt_author; } SVN_ERR(svn_subst_build_keywords2 (&kw, keywords->data, apr_psprintf(pool, fmt, entry->cmt_rev), entry->url, tm, author, pool)); } SVN_ERR(svn_subst_copy_and_translate3(base, to, eol, FALSE, kw, TRUE, special ? TRUE : FALSE, pool)); if (executable) SVN_ERR(svn_io_set_file_executable(to, TRUE, FALSE, pool)); if (! special) SVN_ERR(svn_io_set_file_affected_time(tm, to, pool)); return SVN_NO_ERROR;}static svn_error_t *copy_versioned_files(const char *from, const char *to, svn_opt_revision_t *revision, svn_boolean_t force, svn_boolean_t recurse, const char *native_eol, svn_client_ctx_t *ctx, apr_pool_t *pool){ svn_wc_adm_access_t *adm_access; const svn_wc_entry_t *entry; svn_error_t *err; apr_pool_t *iterpool; apr_hash_t *entries; apr_hash_index_t *hi; apr_finfo_t finfo; SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, from, FALSE, 0, ctx->cancel_func, ctx->cancel_baton, pool)); SVN_ERR(svn_wc_entry(&entry, from, adm_access, FALSE, pool)); /* Bail if we're trying to export something that doesn't exist, or isn't under version control. */ if (! entry) { SVN_ERR(svn_wc_adm_close(adm_access)); return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL, _("'%s' is not under version control " "or doesn't exist"), svn_path_local_style(from, pool)); } /* Only export 'added' files when the revision is WORKING. Otherwise, skip the 'added' files, since they didn't exist in the BASE revision and don't have an associated text-base. Don't export 'deleted' files and directories unless it's a revision other than WORKING. These files and directories don't really exist in WORKING. */ if ((revision->kind != svn_opt_revision_working && entry->schedule == svn_wc_schedule_add) || (revision->kind == svn_opt_revision_working && entry->schedule == svn_wc_schedule_delete)) return SVN_NO_ERROR; if (entry->kind == svn_node_dir) { /* Try to make the new directory. If this fails because the directory already exists, check our FORCE flag to see if we care. */ SVN_ERR(svn_io_stat(&finfo, from, APR_FINFO_PROT, pool)); err = svn_io_dir_make(to, finfo.protection, pool); if (err) { if (! APR_STATUS_IS_EEXIST(err->apr_err)) return err; if (! force) SVN_ERR_W(err, _("Destination directory exists, and will not be " "overwritten unless forced")); else svn_error_clear(err); } SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, pool)); iterpool = svn_pool_create(pool); for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi)) { const char *item; const void *key; void *val; svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); item = key; entry = val; if (ctx->cancel_func) SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); /* ### We could also invoke ctx->notify_func somewhere in ### here... Is it called for, though? Not sure. */ if (entry->kind == svn_node_dir) { if (strcmp(item, SVN_WC_ENTRY_THIS_DIR) == 0) { ; /* skip this, it's the current directory that we're handling now. */ } else { if (recurse) { const char *new_from = svn_path_join(from, item, iterpool); const char *new_to = svn_path_join(to, item, iterpool); SVN_ERR(copy_versioned_files(new_from, new_to, revision, force, recurse, native_eol, ctx, iterpool)); } } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?