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

📄 update_editor.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * update_editor.c :  main editor for checkouts and updates * * ==================================================================== * Copyright (c) 2000-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 <stdlib.h>#include <string.h>#include <assert.h>#include <apr_pools.h>#include <apr_hash.h>#include <apr_md5.h>#include <apr_tables.h>#include <apr_file_io.h>#include <apr_strings.h>#include "svn_types.h"#include "svn_pools.h"#include "svn_delta.h"#include "svn_string.h"#include "svn_path.h"#include "svn_xml.h"#include "svn_error.h"#include "svn_io.h"#include "svn_md5.h"#include "svn_wc.h"#include "svn_private_config.h"#include "svn_time.h"#include "wc.h"#include "log.h"#include "adm_files.h"#include "adm_ops.h"#include "entries.h"#include "lock.h"#include "props.h"#include "translate.h"/*** batons ***/struct edit_baton{  /* For updates, the "destination" of the edit is the ANCHOR (the     directory at which the edit is rooted) plus the TARGET (the     actual thing we wish to update).  For checkouts, ANCHOR holds the     whole path, and TARGET is unused. */  const char *anchor;  const char *target;  /* ADM_ACCESS is an access baton that includes the ANCHOR directory */  svn_wc_adm_access_t *adm_access;  /* The revision we're targeting...or something like that.  This     starts off as a pointer to the revision to which we are updating,     or SVN_INVALID_REVNUM, but by the end of the edit, should be     pointing to the final revision. */  svn_revnum_t *target_revision;  /* Whether this edit will descend into subdirs */  svn_boolean_t recurse;  /* Need to know if the user wants us to overwrite the 'now' times on     edited/added files with the last-commit-time. */  svn_boolean_t use_commit_times;  /* Was the root actually opened (was this a non-empty edit)? */  svn_boolean_t root_opened;  /* Was the update-target deleted?  This is a special situation. */  svn_boolean_t target_deleted;   /* Non-null if this is a 'switch' operation. */  const char *switch_url;  /* The URL to the root of the repository, or NULL. */  const char *repos;  /* External diff3 to use for merges (can be null, in which case     internal merge code is used). */  const char *diff3_cmd;  /* Object for gathering info to be accessed after the edit is     complete. */  svn_wc_traversal_info_t *traversal_info;  /* This editor sends back notifications as it edits. */  svn_wc_notify_func2_t notify_func;  void *notify_baton;  /* This editor is normally wrapped in a cancellation editor anyway,     so it doesn't bother to check for cancellation itself.  However,     it needs a cancel_func and cancel_baton available to pass to     long-running functions. */  svn_cancel_func_t cancel_func;  void *cancel_baton;  apr_pool_t *pool;};struct dir_baton{  /* The path to this directory. */  const char *path;  /* Basename of this directory. */  const char *name;  /* The repository URL this directory will correspond to. */  const char *new_URL;  /* The global edit baton. */  struct edit_baton *edit_baton;  /* Baton for this directory's parent, or NULL if this is the root     directory. */  struct dir_baton *parent_baton;  /* Gets set iff this is a new directory that is not yet versioned and not     yet in the parent's list of entries */  svn_boolean_t added;  /* An array of svn_prop_t structures, representing all the property     changes to be applied to this directory. */  apr_array_header_t *propchanges;  /* The bump information for this directory. */  struct bump_dir_info *bump_info;  /* The current log file number. */  int log_number;  /* The pool in which this baton itself is allocated. */  apr_pool_t *pool;};/* The bump information is tracked separately from the directory batons.   This is a small structure kept in the edit pool, while the heavier   directory baton is managed by the editor driver.   In a postfix delta case, the directory batons are going to disappear.   The files will refer to these structures, rather than the full   directory baton.  */struct bump_dir_info{  /* ptr to the bump information for the parent directory */  struct bump_dir_info *parent;  /* how many entries are referring to this bump information? */  int ref_count;  /* the path of the directory to bump */  const char *path;};struct handler_baton{  apr_file_t *source;  apr_file_t *dest;  svn_txdelta_window_handler_t apply_handler;  void *apply_baton;  apr_pool_t *pool;  struct file_baton *fb;};/* Return the url for NAME in DIR, allocated in POOL, or null if * unable to obtain a url.  If NAME is null, get the url for DIR. *  * Use ASSOCIATED_ACCESS to retrieve an access baton for PATH, and do * all temporary allocation in POOL.  */static const char *get_entry_url(svn_wc_adm_access_t *associated_access,              const char *dir,              const char *name,              apr_pool_t *pool){  svn_error_t *err;  const svn_wc_entry_t *entry;  svn_wc_adm_access_t *adm_access;  err = svn_wc_adm_retrieve(&adm_access, associated_access, dir, pool);  if (! err)    {      /* Note that `name' itself may be NULL. */      err = svn_wc_entry(&entry, svn_path_join_many(pool, dir, name, NULL),                         adm_access, FALSE, pool);    }  if (err || (! entry) || (! entry->url))    {      if (err)        svn_error_clear(err);      return NULL;    }  return entry->url;}/* An APR pool cleanup handler.  This runs the log file for a   directory baton. */static apr_status_tcleanup_dir_baton(void *dir_baton){  struct dir_baton *db = dir_baton;  svn_error_t *err;  apr_status_t apr_err;  svn_wc_adm_access_t *adm_access;  /* If there are no log files to write, return immediately. */  if (db->log_number == 0)    return APR_SUCCESS;  err = svn_wc_adm_retrieve(&adm_access, db->edit_baton->adm_access,                            db->path, apr_pool_parent_get(db->pool));  if (! err)    {      err = svn_wc__run_log(adm_access, NULL, apr_pool_parent_get(db->pool));            if (! err)        return APR_SUCCESS;    }    apr_err = err->apr_err;  svn_error_clear(err);  return apr_err;}/* An APR pool cleanup handler.  This is a child handler, it removes   the mail pool handler. */static apr_status_tcleanup_dir_baton_child(void *dir_baton){  struct dir_baton *db = dir_baton;  apr_pool_cleanup_kill(db->pool, db, cleanup_dir_baton);  return APR_SUCCESS;}    /* Return a new dir_baton to represent NAME (a subdirectory of   PARENT_BATON).  If PATH is NULL, this is the root directory of the   edit. */static struct dir_baton *make_dir_baton(const char *path,               struct edit_baton *eb,               struct dir_baton *pb,               svn_boolean_t added,               apr_pool_t *pool){  struct dir_baton *d = apr_pcalloc(pool, sizeof(*d));  struct bump_dir_info *bdi;    /* Don't do this.  Just do NOT do this to me. */  if (pb && (! path))    abort();  /* Construct the PATH and baseNAME of this directory. */  d->path = apr_pstrdup(pool, eb->anchor);  if (path)    {      d->path = svn_path_join(d->path, path, pool);      d->name = svn_path_basename(path, pool);    }  else    {      d->name = NULL;    }  /* Figure out the new_URL for this directory. */  if (eb->switch_url)    {      /* Switches are, shall we say, complex.  If this directory is         the root directory (it has no parent), then it either gets         the SWITCH_URL for its own (if it is both anchor and target)         or the parent of the SWITCH_URL (if it is anchor, but there's         another target). */      if (! pb)        {          if (! *eb->target) /* anchor is also target */            d->new_URL = apr_pstrdup(pool, eb->switch_url);          else            d->new_URL = svn_path_dirname(eb->switch_url, pool);        }      /* Else this directory is *not* the root (has a parent).  If it         is the target (there is a target, and this directory has no         grandparent), then it gets the SWITCH_URL for its own.         Otherwise, it gets a child of its parent's URL. */      else        {          if (*eb->target && (! pb->parent_baton))            d->new_URL = apr_pstrdup(pool, eb->switch_url);          else            d->new_URL = svn_path_url_add_component(pb->new_URL,                                                     d->name, pool);        }    }  else  /* must be an update */    {      /* updates are the odds ones.  if we're updating a path already         present on disk, we use its original URL.  otherwise, we'll         telescope based on its parent's URL. */      d->new_URL = get_entry_url(eb->adm_access, d->path, NULL, pool);      if ((! d->new_URL) && pb)        d->new_URL = svn_path_url_add_component(pb->new_URL, d->name, pool);    }  /* the bump information lives in the edit pool */  bdi = apr_palloc(eb->pool, sizeof(*bdi));  bdi->parent = pb ? pb->bump_info : NULL;  bdi->ref_count = 1;  bdi->path = apr_pstrdup(eb->pool, d->path);  /* the parent's bump info has one more referer */  if (pb)    ++bdi->parent->ref_count;  d->edit_baton   = eb;  d->parent_baton = pb;  d->pool         = svn_pool_create(pool);  d->propchanges  = apr_array_make(pool, 1, sizeof(svn_prop_t));  d->added        = added;  d->bump_info    = bdi;  d->log_number   = 0;  apr_pool_cleanup_register(d->pool, d, cleanup_dir_baton,                            cleanup_dir_baton_child);    return d;}/* Helper for maybe_bump_dir_info():   In a single atomic action, (1) remove any 'deleted' entries from a   directory, (2) remove any 'absent' entries whose revision numbers   are different from the parent's new target revision, (3) remove any   'missing' dir entries, and (4) remove the directory's 'incomplete'   flag. */static svn_error_t *complete_directory(struct edit_baton *eb,                   const char *path,                   svn_boolean_t is_root_dir,                   apr_pool_t *pool){  svn_wc_adm_access_t *adm_access;  apr_hash_t *entries;  svn_wc_entry_t *entry;  apr_hash_index_t *hi;  apr_pool_t *subpool;  svn_wc_entry_t *current_entry;  const char *name;  /* If this is the root directory and there is a target, we can't     mark this directory complete. */  if (is_root_dir && *eb->target)    return SVN_NO_ERROR;

⌨️ 快捷键说明

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