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

📄 update_editor.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* All operations are on the in-memory entries hash. */  SVN_ERR(svn_wc_adm_retrieve(&adm_access, eb->adm_access, path, pool));  SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE, pool));  /* Mark THIS_DIR complete. */  entry = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);  if (! entry)    return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,                             _("No '.' entry in: '%s'"),                             svn_path_local_style(path, pool));  entry->incomplete = FALSE;  /* Remove any deleted or missing entries. */  subpool = svn_pool_create(pool);  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))    {      const void *key;      void *val;      svn_pool_clear(subpool);      apr_hash_this(hi, &key, NULL, &val);      name = key;      current_entry = val;            /* Any entry still marked as deleted (and not schedule add) can now         be removed -- if it wasn't undeleted by the update, then it         shouldn't stay in the updated working set.  Schedule add items         should remain.      */      if (current_entry->deleted)        {          if (current_entry->schedule != svn_wc_schedule_add)            svn_wc__entry_remove(entries, name);          else            {              svn_wc_entry_t tmpentry;              tmpentry.deleted = FALSE;              SVN_ERR(svn_wc__entry_modify(adm_access, current_entry->name,                                           &tmpentry,                                           SVN_WC__ENTRY_MODIFY_DELETED,                                           FALSE, subpool));            }        }      /* An absent entry might have been reconfirmed as absent, and the way         we can tell is by looking at its revision number: a revision         number different from the target revision of the update means the         update never mentioned the item, so the entry should be         removed. */      else if (current_entry->absent               && (current_entry->revision != *(eb->target_revision)))        {          svn_wc__entry_remove(entries, name);        }      else if (current_entry->kind == svn_node_dir)        {          const char *child_path = svn_path_join(path, name, subpool);                    if ((svn_wc__adm_missing(adm_access, child_path))              && (! current_entry->absent)              && (current_entry->schedule != svn_wc_schedule_add))            {              svn_wc__entry_remove(entries, name);              if (eb->notify_func)                {                  svn_wc_notify_t *notify                    = svn_wc_create_notify(child_path,                                           svn_wc_notify_update_delete,                                           subpool);                  notify->kind = current_entry->kind;                  (* eb->notify_func)(eb->notify_baton, notify, subpool);                }            }        }    }  svn_pool_destroy(subpool);  /* An atomic write of the whole entries file. */  SVN_ERR(svn_wc__entries_write(entries, adm_access, pool));  return SVN_NO_ERROR;}/* Decrement the bump_dir_info's reference count. If it hits zero,   then this directory is "done". This means it is safe to remove the   'incomplete' flag attached to the THIS_DIR entry.   In addition, when the directory is "done", we loop onto the parent's   bump information to possibly mark it as done, too.*/static svn_error_t *maybe_bump_dir_info(struct edit_baton *eb,                    struct bump_dir_info *bdi,                    apr_pool_t *pool){  /* Keep moving up the tree of directories until we run out of parents,     or a directory is not yet "done".  */  for ( ; bdi != NULL; bdi = bdi->parent)    {      if (--bdi->ref_count > 0)        return SVN_NO_ERROR;    /* directory isn't done yet */      /* The refcount is zero, so we remove any 'dead' entries from         the directory and mark it 'complete'.  */      SVN_ERR(complete_directory(eb, bdi->path,                                  bdi->parent ? FALSE : TRUE, pool));    }  /* we exited the for loop because there are no more parents */  return SVN_NO_ERROR;}struct file_baton{  /* The global edit baton. */  struct edit_baton *edit_baton;  /* The parent directory of this file. */  struct dir_baton *dir_baton;  /* Pool specific to this file_baton. */  apr_pool_t *pool;  /* Name of this file (its entry in the directory). */  const char *name;  /* Path to this file, either abs or relative to the change-root. */  const char *path;  /* The repository URL this file will correspond to. */  const char *new_URL;  /* Set if this file is new. */  svn_boolean_t added;  /* This gets set if the file underwent a text change, which guides     the code that syncs up the adm dir and working copy. */  svn_boolean_t text_changed;  /* This gets set if the file underwent a prop change, which guides     the code that syncs up the adm dir and working copy. */  svn_boolean_t prop_changed;  /* An array of svn_prop_t structures, representing all the property     changes to be applied to this file. */  apr_array_header_t *propchanges;  /* The last-changed-date of the file.  This is actually a property     that comes through as an 'entry prop', and will be used to set     the working file's timestamp if it's added.  */  const char *last_changed_date;  /* Bump information for the directory this file lives in */  struct bump_dir_info *bump_info;  /* This is initialized to all zeroes when the baton is created, then     populated with the MD5 digest of the resultant fulltext after the     last window is handled by the handler returned from     apply_textdelta(). */   unsigned char digest[APR_MD5_DIGESTSIZE];};/* Make a new file baton in the provided POOL, with PB as the parent baton.   PATH is relative to the root of the edit. */static struct file_baton *make_file_baton(struct dir_baton *pb,                const char *path,                svn_boolean_t adding,                apr_pool_t *pool){  struct file_baton *f = apr_pcalloc(pool, sizeof(*f));  /* I rather need this information, yes. */  if (! path)    abort();  /* Make the file's on-disk name. */  f->path = svn_path_join(pb->edit_baton->anchor, path, pool);  f->name = svn_path_basename(path, pool);  /* Figure out the new_URL for this file. */  if (pb->edit_baton->switch_url)    {      f->new_URL = svn_path_url_add_component(pb->new_URL, f->name, pool);    }  else     {      f->new_URL = get_entry_url(pb->edit_baton->adm_access,                                 pb->path, f->name, pool);    }  f->pool         = pool;  f->edit_baton   = pb->edit_baton;  f->propchanges  = apr_array_make(pool, 1, sizeof(svn_prop_t));  f->bump_info    = pb->bump_info;  f->added        = adding;  f->dir_baton    = pb;  /* No need to initialize f->digest, since we used pcalloc(). */  /* the directory's bump info has one more referer now */  ++f->bump_info->ref_count;  return f;}/*** Helpers for the editor callbacks. ***/static svn_error_t *window_handler(svn_txdelta_window_t *window, void *baton){  struct handler_baton *hb = baton;  struct file_baton *fb = hb->fb;  svn_error_t *err = SVN_NO_ERROR, *err2 = SVN_NO_ERROR;  /* Apply this window.  We may be done at that point.  */  err = hb->apply_handler(window, hb->apply_baton);  if (window != NULL && err == SVN_NO_ERROR)    return err;  /* Either we're done (window is NULL) or we had an error.  In either     case, clean up the handler.  */  if (hb->source)    {      err2 = svn_wc__close_text_base(hb->source, fb->path, 0, fb->pool);      if (err2 != SVN_NO_ERROR && err == SVN_NO_ERROR)        err = err2;      else        svn_error_clear(err2);    }  err2 = svn_wc__close_text_base(hb->dest, fb->path, 0, fb->pool);  if (err2 != SVN_NO_ERROR)    {      if (err == SVN_NO_ERROR)        err = err2;      else        svn_error_clear(err2);    }  svn_pool_destroy(hb->pool);  if (err != SVN_NO_ERROR)    {      /* We failed to apply the patch; clean up the temporary file.  */      const char *tmppath = svn_wc__text_base_path(fb->path, TRUE, fb->pool);      apr_file_remove(tmppath, fb->pool);    }  else    {      /* Leave a note in the baton indicating that there's new text to         sync up.  */      fb->text_changed = 1;    }  return err;}/* Prepare directory for dir_baton DB for updating or checking out. * * If the path already exists, but is not a working copy for * ANCESTOR_URL and ANCESTOR_REVISION, then an error will be returned.  */static svn_error_t *prep_directory(struct dir_baton *db,               const char *ancestor_url,               svn_revnum_t ancestor_revision,               apr_pool_t *pool){  const char *repos;  /* Make sure the directory exists. */  SVN_ERR(svn_wc__ensure_directory(db->path, pool));  /* Use the repository root of the anchor, but only if it actually is an     ancestor of the URL of this directory. */  if (db->edit_baton->repos      && svn_path_is_ancestor(db->edit_baton->repos, ancestor_url))    repos = db->edit_baton->repos;  else    repos = NULL;  /* Make sure it's the right working copy, either by creating it so,     or by checking that it is so already. */  SVN_ERR(svn_wc_ensure_adm2(db->path, NULL,                             ancestor_url, repos,                             ancestor_revision, pool));  if (! db->edit_baton->adm_access      || strcmp(svn_wc_adm_access_path(db->edit_baton->adm_access),                db->path))    {      svn_wc_adm_access_t *adm_access;      apr_pool_t *adm_access_pool        = db->edit_baton->adm_access        ? svn_wc_adm_access_pool(db->edit_baton->adm_access)        : db->edit_baton->pool;      SVN_ERR(svn_wc_adm_open3(&adm_access, db->edit_baton->adm_access,                               db->path, TRUE, 0, NULL, NULL,                               adm_access_pool));      if (!db->edit_baton->adm_access)        db->edit_baton->adm_access = adm_access;    }    return SVN_NO_ERROR;}/* Accumulate tags in LOG_ACCUM to set ENTRY_PROPS for BASE_NAME.   ENTRY_PROPS is an array of svn_prop_t* entry props.   If ENTRY_PROPS contains the removal of a lock token, all entryprops   related to a lock will be removed and LOCK_STATE, if non-NULL, will be   set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL   will be set to svn_wc_lock_state_unchanged. */static svn_error_t *accumulate_entry_props(svn_stringbuf_t *log_accum,                       svn_wc_notify_lock_state_t *lock_state,                       svn_wc_adm_access_t *adm_access,                       const char *base_name,                       apr_array_header_t *entry_props,                       apr_pool_t *pool){  int i;  svn_wc_entry_t tmp_entry;  apr_uint32_t flags = 0;  if (lock_state)    *lock_state = svn_wc_notify_lock_state_unchanged;  for (i = 0; i < entry_props->nelts; ++i)    {      const svn_prop_t *prop = &APR_ARRAY_IDX(entry_props, i, svn_prop_t);      const char *val;      /* The removal of the lock-token entryprop means that the lock was         defunct. */      if (! strcmp(prop->name, SVN_PROP_ENTRY_LOCK_TOKEN))        {          SVN_ERR(svn_wc__loggy_delete_lock(&log_accum, adm_access,                                            base_name, pool));          if (lock_state)            *lock_state = svn_wc_notify_lock_state_unlocked;          continue;        }      /* A prop value of NULL means the information was not         available.  We don't remove this field from the entries         file; we have convention just leave it empty.  So let's         just skip those entry props that have no values. */      if (! prop->value)        continue;      val = prop->value->data;      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))        {          flags |= SVN_WC__ENTRY_MODIFY_CMT_AUTHOR;          tmp_entry.cmt_author = val;        }      else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_REV))        {          flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;          tmp_entry.cmt_rev = SVN_STR_TO_REV(val);        }      else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_DATE))        {          flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;          SVN_ERR(svn_time_from_cstring(&tmp_entry.cmt_date, val, pool));        }      else if (! strcmp(prop->name, SVN_PROP_ENTRY_UUID))        {          flags |= SVN_WC__ENTRY_MODIFY_UUID;

⌨️ 快捷键说明

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