⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relocate.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
字号:
/* * relocate.c: do wc repos relocation * * ==================================================================== * Copyright (c) 2002-2006 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 "svn_wc.h"#include "svn_error.h"#include "svn_pools.h"#include "svn_path.h"#include "wc.h"#include "entries.h"#include "lock.h"#include "props.h"#include "svn_private_config.h"/* Relocate the main URL and the copyfrom URL for ENTRY by changing FROM to * TO.  ADM_ACCESS is the access baton for ENTRY.  If DO_SYNC is set then * the new entry will be written to disk immediately, otherwise only the * entries cache will be affected.  Calls VALIDATOR passing VALIDATOR_BATON * to validate new URLs. */static svn_error_t *relocate_entry(svn_wc_adm_access_t *adm_access,               const svn_wc_entry_t *entry,               const char *from,               const char *to,               svn_wc_relocation_validator2_t validator,               void *validator_baton,               svn_boolean_t do_sync,               apr_pool_t *pool){  svn_wc_entry_t entry2;  apr_uint32_t flags = 0;  apr_size_t from_len = strlen(from);  if (entry->repos)    {      /* We can't relocate beyond the repository root, but the user is allowed         to specify a redundant part of the fs path in from and to, but only         if this part is identical in both strings. */      apr_size_t repos_len = strlen(entry->repos);                 if (from_len >= repos_len)        {          apr_size_t to_len = strlen(to);          apr_size_t fs_path_len = from_len - repos_len;          if (to_len < fs_path_len              || strncmp(from + repos_len, to + (to_len - fs_path_len),                         fs_path_len) != 0)            return svn_error_create(SVN_ERR_WC_INVALID_RELOCATION, NULL,                                    _("Relocate can only change the "                                      "repository part of an URL"));          /* Since the fs path part is redundant, we don't need to change             that part anyway, and the below code depends on this. */          from_len = repos_len;          to = apr_pstrndup(pool, to, to_len - fs_path_len);        }      if (strncmp(from, entry->repos, from_len) == 0)        {          entry2.repos = apr_pstrcat(pool, to, entry->repos + from_len, NULL);          flags |= SVN_WC__ENTRY_MODIFY_REPOS;          /* Make sure to is really the repository root. */          SVN_ERR(validator(validator_baton, entry->uuid, entry2.repos,                            TRUE, pool));        }    }  if (entry->url && ! strncmp(entry->url, from, from_len))    {      entry2.url = apr_pstrcat(pool, to, entry->url + from_len, NULL);      if (entry->uuid)        SVN_ERR(validator(validator_baton, entry->uuid, entry2.url, FALSE,                          pool));      flags |= SVN_WC__ENTRY_MODIFY_URL;    }  if (entry->copyfrom_url && ! strncmp(entry->copyfrom_url, from, from_len))    {      entry2.copyfrom_url = apr_pstrcat(pool, to,                                        entry->copyfrom_url + from_len, NULL);      if (entry->uuid)        SVN_ERR(validator(validator_baton, entry->uuid,                          entry2.copyfrom_url, FALSE, pool));      flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL;    }  if (flags)    SVN_ERR(svn_wc__entry_modify(adm_access, entry->name,                                 &entry2, flags, do_sync, pool));  return SVN_NO_ERROR;}svn_error_t *svn_wc_relocate2(const char *path,                 svn_wc_adm_access_t *adm_access,                 const char *from,                 const char *to,                 svn_boolean_t recurse,                 svn_wc_relocation_validator2_t validator,                 void *validator_baton,                 apr_pool_t *pool){  apr_hash_t *entries;  apr_hash_index_t *hi;  const svn_wc_entry_t *entry;  apr_pool_t *subpool;  SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, pool));  if (! entry)    return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, NULL, NULL);  if (entry->kind == svn_node_file)    {      SVN_ERR(relocate_entry(adm_access, entry, from, to,                             validator, validator_baton, TRUE /* sync */,                             pool));      return SVN_NO_ERROR;    }  /* Relocate THIS_DIR first, in order to pre-validate the relocated URL     of all of the other entries.  This is technically cheating because     it relies on knowledge of the libsvn_client implementation, but it     significantly cuts down on the number of expensive validations the     validator has to do.  ### Should svn_wc.h document the ordering? */  SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE, pool));  entry = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);  SVN_ERR(relocate_entry(adm_access, entry, from, to,                         validator, validator_baton, FALSE, pool));  subpool = svn_pool_create(pool);  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))    {      const void *key;      void *val;      apr_hash_this(hi, &key, NULL, &val);      entry = val;      if (strcmp(key, SVN_WC_ENTRY_THIS_DIR) == 0)        continue;      svn_pool_clear(subpool);      if (recurse && (entry->kind == svn_node_dir)          && (! entry->deleted || (entry->schedule == svn_wc_schedule_add))          && ! entry->absent)        {          svn_wc_adm_access_t *subdir_access;          const char *subdir = svn_path_join(path, key, subpool);          if (svn_wc__adm_missing(adm_access, subdir))            continue;          SVN_ERR(svn_wc_adm_retrieve(&subdir_access, adm_access,                                       subdir, subpool));          SVN_ERR(svn_wc_relocate2(subdir, subdir_access, from, to,                                   recurse, validator,                                    validator_baton, subpool));        }      SVN_ERR(relocate_entry(adm_access, entry, from, to,                             validator, validator_baton, FALSE, subpool));    }  svn_pool_destroy(subpool);  SVN_ERR(svn_wc__remove_wcprops(adm_access, NULL, FALSE, pool));  SVN_ERR(svn_wc__entries_write(entries, adm_access, pool));  return SVN_NO_ERROR;}/* Compatibility baton and wrapper. */struct compat_baton {  svn_wc_relocation_validator_t validator;  void *baton;};/* This implements svn_wc_relocate_validator2_t. */static svn_error_t *compat_validator(void *baton,                 const char *uuid,                 const char *url,                 svn_boolean_t root,                 apr_pool_t *pool){  struct compat_baton *cb = baton;  /* The old callback type doesn't allow uuid to be NULL. */  if (uuid)    return cb->validator(cb->baton, uuid, url);  return SVN_NO_ERROR;}svn_error_t *svn_wc_relocate(const char *path,                svn_wc_adm_access_t *adm_access,                const char *from,                const char *to,                svn_boolean_t recurse,                svn_wc_relocation_validator_t validator,                void *validator_baton,                apr_pool_t *pool){  struct compat_baton cb;  cb.validator = validator;  cb.baton = validator_baton;  return svn_wc_relocate2(path, adm_access, from, to, recurse,                          compat_validator, &cb, pool);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -