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

📄 update_editor.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
static svn_error_t *add_file(const char *name,         void *parent_baton,         const char *copyfrom_path,         svn_revnum_t copyfrom_revision,         apr_pool_t *pool,         void **file_baton){  return add_or_open_file(name, parent_baton, copyfrom_path,                           copyfrom_revision, file_baton, TRUE, pool);}static svn_error_t *open_file(const char *name,          void *parent_baton,          svn_revnum_t base_revision,          apr_pool_t *pool,          void **file_baton){  return add_or_open_file(name, parent_baton, NULL, base_revision,                           file_baton, FALSE, pool);}static svn_error_t *apply_textdelta(void *file_baton,                 const char *base_checksum,                apr_pool_t *pool,                svn_txdelta_window_handler_t *handler,                void **handler_baton){  struct file_baton *fb = file_baton;  struct edit_baton *eb = fb->edit_baton;  apr_pool_t *handler_pool = svn_pool_create(fb->pool);  struct handler_baton *hb = apr_palloc(handler_pool, sizeof(*hb));  svn_error_t *err;  svn_wc_adm_access_t *adm_access;  const svn_wc_entry_t *ent;  svn_boolean_t replaced;  /* Open the text base for reading, unless this is a checkout. */  hb->source = NULL;  /*      kff todo: what we really need to do here is:            1. See if there's a file or dir by this name already here.     2. See if it's under revision control.     3. If both are true, open text-base.     4. If only 1 is true, bail, because we can't go destroying user's        files (or as an alternative to bailing, move it to some tmp        name and somehow tell the user, but communicating with the        user without erroring is a whole callback system we haven't        finished inventing yet.)  */  /* Before applying incoming svndiff data to text base, make sure     text base hasn't been corrupted, and that its checksum     matches the expected base checksum. */  SVN_ERR(svn_wc_adm_retrieve(&adm_access, eb->adm_access,                              svn_path_dirname(fb->path, pool), pool));  SVN_ERR(svn_wc_entry(&ent, fb->path, adm_access, FALSE, pool));  replaced = ent && ent->schedule == svn_wc_schedule_replace;  /* Only compare checksums this file has an entry, and the entry has     a checksum.  If there's no entry, it just means the file is     created in this update, so there won't be any previously recorded     checksum to compare against.  If no checksum, well, for backwards     compatibility we assume that no checksum always matches. */  if (ent && ent->checksum)    {      unsigned char digest[APR_MD5_DIGESTSIZE];      const char *hex_digest;      const char *tb;      if (replaced)        tb = svn_wc__text_revert_path(fb->path, FALSE, pool);      else        tb = svn_wc__text_base_path(fb->path, FALSE, pool);      SVN_ERR(svn_io_file_checksum(digest, tb, pool));      hex_digest = svn_md5_digest_to_cstring_display(digest, pool);            /* Compare the base_checksum here, rather than in the window         handler, because there's no guarantee that the handler will         see every byte of the base file. */      if (base_checksum)        {          if (strcmp(hex_digest, base_checksum) != 0)            return svn_error_createf              (SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,               _("Checksum mismatch for '%s'; expected: '%s', actual: '%s'"),               svn_path_local_style(tb, pool), base_checksum, hex_digest);        }            if (! replaced && strcmp(hex_digest, ent->checksum) != 0)        {          return svn_error_createf            (SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,             _("Checksum mismatch for '%s'; recorded: '%s', actual: '%s'"),             svn_path_local_style(tb, pool), ent->checksum, hex_digest);        }    }  if (replaced)    err = svn_wc__open_revert_base(&hb->source, fb->path,                                   APR_READ,                                   handler_pool);  else    err = svn_wc__open_text_base(&hb->source, fb->path, APR_READ,                                 handler_pool);  if (err && !APR_STATUS_IS_ENOENT(err->apr_err))    {      if (hb->source)        {          if (replaced)            svn_error_clear(svn_wc__close_revert_base(hb->source, fb->path,                                                      0, handler_pool));          else            svn_error_clear(svn_wc__close_text_base(hb->source, fb->path,                                                    0, handler_pool));        }      svn_pool_destroy(handler_pool);      return err;    }  else if (err)    {      svn_error_clear(err);      hb->source = NULL;  /* make sure */    }  /* Open the text base for writing (this will get us a temporary file).  */  hb->dest = NULL;  if (replaced)    err = svn_wc__open_revert_base(&hb->dest, fb->path,                                   (APR_WRITE | APR_TRUNCATE | APR_CREATE),                                   handler_pool);  else    err = svn_wc__open_text_base(&hb->dest, fb->path,                                 (APR_WRITE | APR_TRUNCATE | APR_CREATE),                                 handler_pool);  if (err)    {      if (hb->dest)        {          if (replaced)            svn_error_clear(svn_wc__close_revert_base(hb->dest, fb->path, 0,                                                      handler_pool));          else            svn_error_clear(svn_wc__close_text_base(hb->dest, fb->path, 0,                                                    handler_pool));        }      svn_pool_destroy(handler_pool);      return err;    }    /* Prepare to apply the delta.  */  {    const char *tmp_path;    apr_file_name_get(&tmp_path, hb->dest);    svn_txdelta_apply(svn_stream_from_aprfile(hb->source, handler_pool),                      svn_stream_from_aprfile(hb->dest, handler_pool),                      fb->digest, tmp_path, handler_pool,                      &hb->apply_handler, &hb->apply_baton);  }    hb->pool = handler_pool;  hb->fb = fb;    /* We're all set.  */  *handler_baton = hb;  *handler = window_handler;  return SVN_NO_ERROR;}static svn_error_t *change_file_prop(void *file_baton,                 const char *name,                 const svn_string_t *value,                 apr_pool_t *pool){  struct file_baton *fb = file_baton;  struct edit_baton *eb = fb->edit_baton;  svn_prop_t *propchange;  /* Push a new propchange to the file baton's array of propchanges */  propchange = apr_array_push(fb->propchanges);  propchange->name = apr_pstrdup(fb->pool, name);  propchange->value = value ? svn_string_dup(value, fb->pool) : NULL;  /* Let close_file() know that propchanges are waiting to be     applied. */  fb->prop_changed = 1;  /* Special case: if the file is added during a checkout, cache the     last-changed-date propval for future use. */  if (eb->use_commit_times      && (strcmp(name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0)      && value)    fb->last_changed_date = apr_pstrdup(fb->pool, value->data);  return SVN_NO_ERROR;}/* Write log commands to merge PROP_CHANGES into the existing properties of   FILE_PATH.  PROP_CHANGES can contain regular properties as well as   entryprops and wcprops.  Update *PROP_STATE (unless PROP_STATE is NULL)   to reflect the result of the regular prop merge.   Make *LOCK_STATE reflect the possible removal of a lock token from   FILE_PATH's entryprops.   ADM_ACCESS is the access baton for FILE_PATH.  Append log commands to   LOG_ACCUM.  Use POOL for temporary allocations. */static svn_error_t *merge_props(svn_stringbuf_t *log_accum,            svn_wc_notify_state_t *prop_state,            svn_wc_notify_lock_state_t *lock_state,            svn_wc_adm_access_t *adm_access,            const char *file_path,            const apr_array_header_t *prop_changes,            apr_pool_t *pool){  apr_array_header_t *regular_props = NULL, *wc_props = NULL,    *entry_props = NULL;  const char *base_name;  svn_path_split(file_path, NULL, &base_name, pool);  /* Sort the property list into three arrays, based on kind. */  SVN_ERR(svn_categorize_props(prop_changes,                               &entry_props, &wc_props, &regular_props,                               pool));  /* Always initialize to unknown state. */  if (prop_state)    *prop_state = svn_wc_notify_state_unknown;  /* Merge the 'regular' props into the existing working proplist. */  if (regular_props)    {      /* This will merge the old and new props into a new prop db, and         write <cp> commands to the logfile to install the merged         props.  */      SVN_ERR(svn_wc__merge_props(prop_state,                                  adm_access, base_name,                                  NULL /* use base props */,                                  regular_props, TRUE, FALSE, pool,                                  &log_accum));    }    /* If there are any ENTRY PROPS, make sure those get appended to the     growing log as fields for the file's entry.     Note that no merging needs to happen; these kinds of props aren't     versioned, so if the property is present, we overwrite the value. */    if (entry_props)    SVN_ERR(accumulate_entry_props(log_accum, lock_state,                                   adm_access, base_name,                                   entry_props, pool));  else    *lock_state = svn_wc_notify_lock_state_unchanged;  /* Possibly write log commands to tweak prop entry timestamp. */  if (regular_props)    {      svn_boolean_t prop_modified;      /* Are the working file's props locally modified? */      SVN_ERR(svn_wc_props_modified_p(&prop_modified,                                      file_path, adm_access,                                      pool));      /* Log entry which sets a new property timestamp, but only if         there are no local changes to the props. */      if (! prop_modified)        SVN_ERR(svn_wc__loggy_set_entry_timestamp_from_wc                (&log_accum, adm_access,                 base_name, SVN_WC__ENTRY_ATTR_PROP_TIME, pool));    }  /* This writes a whole bunch of log commands to install wcprops.  */  if (wc_props)    SVN_ERR(accumulate_wcprops(log_accum, adm_access,                               base_name, wc_props, pool));  return SVN_NO_ERROR;}/* Append, to LOG_ACCUM, log commands to update the entry for NAME in   ADM_ACCESS with a NEW_REVISION and a NEW_URL (if non-NULL), making sure   the entry refers to a file and has no absent or deleted state.   Use POOL for temporary allocations. */static svn_error_t *tweak_entry(svn_stringbuf_t *log_accum,            svn_wc_adm_access_t *adm_access,            const char *name,            svn_revnum_t new_revision,            const char *new_URL,            apr_pool_t *pool){  /* Write log entry which will bump the revision number.  Also, just     in case we're overwriting an existing phantom 'deleted' or     'absent' entry, be sure to remove the hiddenness. */  svn_wc_entry_t tmp_entry;  apr_uint32_t modify_flags = SVN_WC__ENTRY_MODIFY_KIND    | SVN_WC__ENTRY_MODIFY_REVISION    | SVN_WC__ENTRY_MODIFY_DELETED    | SVN_WC__ENTRY_MODIFY_ABSENT;  tmp_entry.revision = new_revision;  tmp_entry.kind = svn_node_file;  tmp_entry.deleted = FALSE;  tmp_entry.absent = FALSE;  /* Possibly install a *non*-inherited URL in the entry. */  if (new_URL)    {      tmp_entry.url = new_URL;      modify_flags |= SVN_WC__ENTRY_MODIFY_URL;    }  SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, adm_access,                                     name, &tmp_entry, modify_flags,                                     pool));  return SVN_NO_ERROR;}/* This is the small planet.  It has the complex responsibility of * "integrating" a new revision of a file into a working copy.  * * Given a FILE_PATH either already under version control, or * prepared (see below) to join version control, fully install a * NEW_REVISION of the file;  ADM_ACCESS is an access baton with a * write lock for the directory containing FILE_PATH. * * If FILE_PATH is not already under version control (i.e., does not * have an entry), then the raw data (for example the new text * base and new props) required to put it under version control must * be provided by the caller.  See below for details. * * By "install", we mean: create a new text-base and prop-base, merge * any textual and property changes into the working file, and finally * update all metadata so that the working copy believes it has a new * working revision of the file.  All of this work includes being * sensitive to eol translation, keyword substitution, and performing * all actions accumulated to existing LOG_ACCUM. * * If HAS_NEW_TEXT_BASE is TRUE, the administrative area must contain the * 'new' text base for NEW_REVISION in the temporary text base location. * The temporary text base will be removed after a successful run of the * generated log commands.  If there is no text base, HAS_NEW_TEXT_BASE * must be FALSE. * * The caller also provides the property changes for the file in the * PROP_CHANGES array; if there are no prop changes, then the caller must pass  * NULL instead.  This argument is an array of svn_prop_t structures,  * representing differences against the files existing base properties. * (A deletion is represented by setting an svn_prop_t's 'value' * field to NULL.) * * Note that the PROP_CHANGES array is exp

⌨️ 快捷键说明

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