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

📄 update_editor.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (eb->notify_func)    {      svn_wc_notify_t *notify = svn_wc_create_notify(db->path,                                                     svn_wc_notify_update_add,                                                     pool);      notify->kind = svn_node_dir;      (*eb->notify_func)(eb->notify_baton, notify, pool);    }  return SVN_NO_ERROR;}static svn_error_t *open_directory(const char *path,               void *parent_baton,               svn_revnum_t base_revision,               apr_pool_t *pool,               void **child_baton){  struct dir_baton *pb = parent_baton;  struct edit_baton *eb = pb->edit_baton;  svn_wc_entry_t tmp_entry;  apr_uint32_t flags = SVN_WC__ENTRY_MODIFY_REVISION |    SVN_WC__ENTRY_MODIFY_URL | SVN_WC__ENTRY_MODIFY_INCOMPLETE;                                   svn_wc_adm_access_t *adm_access;  /* kff todo: check that the dir exists locally, find it somewhere if     its not there?  Yes, all this and more...  And ancestor_url and     ancestor_revision need to get used. */  struct dir_baton *db = make_dir_baton(path, eb, pb, FALSE, pool);  *child_baton = db;  /* Mark directory as being at target_revision and URL, but incomplete. */  tmp_entry.revision = *(eb->target_revision);  tmp_entry.url = db->new_URL;  /* In some situations, the URL of this directory does not have the same     repository root as the anchor of the update; we can't just blindly     use the that repository root here, so make sure it is really an     ancestor. */  if (eb->repos && svn_path_is_ancestor(eb->repos, db->new_URL))    {      tmp_entry.repos = eb->repos;      flags |= SVN_WC__ENTRY_MODIFY_REPOS;    }  tmp_entry.incomplete = TRUE;  SVN_ERR(svn_wc_adm_retrieve(&adm_access, eb->adm_access,                              db->path, pool));    SVN_ERR(svn_wc__entry_modify(adm_access, NULL /* THIS_DIR */,                               &tmp_entry, flags,                               TRUE /* immediate write */,                               pool));  return SVN_NO_ERROR;}static svn_error_t *change_dir_prop(void *dir_baton,                const char *name,                const svn_string_t *value,                apr_pool_t *pool){  svn_prop_t *propchange;  struct dir_baton *db = dir_baton;  propchange = apr_array_push(db->propchanges);  propchange->name = apr_pstrdup(db->pool, name);  propchange->value = value ? svn_string_dup(value, db->pool) : NULL;  return SVN_NO_ERROR;}/* If any of the svn_prop_t objects in PROPCHANGES represents a change   to the SVN_PROP_EXTERNALS property, return that change, else return   null.  If PROPCHANGES contains more than one such change, return   the first. */static const svn_prop_t *externals_prop_changed(apr_array_header_t *propchanges){  int i;  for (i = 0; i < propchanges->nelts; i++)    {      const svn_prop_t *p = &(APR_ARRAY_IDX(propchanges, i, svn_prop_t));      if (strcmp(p->name, SVN_PROP_EXTERNALS) == 0)        return p;    }  return NULL;}static svn_error_t *close_directory(void *dir_baton,                apr_pool_t *pool){  struct dir_baton *db = dir_baton;  svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;  apr_array_header_t *entry_props, *wc_props, *regular_props;  svn_wc_adm_access_t *adm_access;        SVN_ERR(svn_categorize_props(db->propchanges, &entry_props, &wc_props,                               &regular_props, pool));  SVN_ERR(svn_wc_adm_retrieve(&adm_access, db->edit_baton->adm_access,                              db->path, db->pool));        /* If this directory has property changes stored up, now is the time     to deal with them. */  if (regular_props->nelts || entry_props->nelts || wc_props->nelts)    {      /* to hold log messages: */      svn_stringbuf_t *entry_accum = svn_stringbuf_create("", db->pool);      if (regular_props->nelts)        {          /* If recording traversal info, then see if the             SVN_PROP_EXTERNALS property on this directory changed,             and record before and after for the change. */          if (db->edit_baton->traversal_info)            {              svn_wc_traversal_info_t *ti = db->edit_baton->traversal_info;              const svn_prop_t *change = externals_prop_changed(regular_props);              if (change)                {                  const svn_string_t *new_val_s = change->value;                  const svn_string_t *old_val_s;                  SVN_ERR(svn_wc_prop_get                          (&old_val_s, SVN_PROP_EXTERNALS,                           db->path, adm_access, db->pool));                  if ((new_val_s == NULL) && (old_val_s == NULL))                    ; /* No value before, no value after... so do nothing. */                  else if (new_val_s && old_val_s                           && (svn_string_compare(old_val_s, new_val_s)))                    ; /* Value did not change... so do nothing. */                  else  /* something changed, record the change */                    {                      /* We can't assume that ti came pre-loaded with the                         old values of the svn:externals property.  Yes,                         most callers will have already initialized ti by                         sending it through svn_wc_crawl_revisions, but we                         shouldn't count on that here -- so we set both the                         old and new values again. */                      if (old_val_s)                        apr_hash_set(ti->externals_old,                                     apr_pstrdup(ti->pool, db->path),                                     APR_HASH_KEY_STRING,                                     apr_pstrmemdup(ti->pool, old_val_s->data,                                                    old_val_s->len));                      if (new_val_s)                        apr_hash_set(ti->externals_new,                                     apr_pstrdup(ti->pool, db->path),                                     APR_HASH_KEY_STRING,                                     apr_pstrmemdup(ti->pool, new_val_s->data,                                                    new_val_s->len));                    }                }            }          /* Merge pending properties into temporary files (ignoring             conflicts). */          SVN_ERR_W(svn_wc__merge_props(&prop_state,                                        adm_access, NULL,                                        NULL /* use baseprops */,                                        regular_props, TRUE, FALSE,                                        db->pool, &entry_accum),                    _("Couldn't do property merge"));        }      SVN_ERR(accumulate_entry_props(entry_accum, NULL,                                     adm_access, SVN_WC_ENTRY_THIS_DIR,                                     entry_props, pool));      SVN_ERR(accumulate_wcprops(entry_accum, adm_access,                                 SVN_WC_ENTRY_THIS_DIR, wc_props, pool));      /* Write our accumulation of log entries into a log file */      SVN_ERR(svn_wc__write_log(adm_access, db->log_number, entry_accum, pool));    }  /* Run the log. */  SVN_ERR(svn_wc__run_log(adm_access, db->edit_baton->diff3_cmd, db->pool));  db->log_number = 0;    /* We're done with this directory, so remove one reference from the     bump information. This may trigger a number of actions. See     maybe_bump_dir_info() for more information.  */  SVN_ERR(maybe_bump_dir_info(db->edit_baton, db->bump_info, db->pool));  /* Notify of any prop changes on this directory -- but do nothing     if it's an added directory, because notification has already     happened in that case. */  if ((! db->added) && (db->edit_baton->notify_func))    {      svn_wc_notify_t *notify        = svn_wc_create_notify(db->path, svn_wc_notify_update_update, pool);      notify->kind = svn_node_dir;      notify->prop_state = prop_state;    (*db->edit_baton->notify_func)(db->edit_baton->notify_baton,                                   notify, pool);    }  return SVN_NO_ERROR;}/* Common code for 'absent_file' and 'absent_directory'. */static svn_error_t *absent_file_or_dir(const char *path,                   svn_node_kind_t kind,                   void *parent_baton,                   apr_pool_t *pool){  const char *name = svn_path_basename(path, pool);  struct dir_baton *pb = parent_baton;  struct edit_baton *eb = pb->edit_baton;  svn_wc_adm_access_t *adm_access;  apr_hash_t *entries;  const svn_wc_entry_t *ent;  svn_wc_entry_t tmp_entry;  /* Extra check: an item by this name may not exist, but there may     still be one scheduled for addition.  That's a genuine     tree-conflict.  */  SVN_ERR(svn_wc_adm_retrieve(&adm_access, eb->adm_access, pb->path, pool));  SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, pool));  ent = apr_hash_get(entries, name, APR_HASH_KEY_STRING);  if (ent && (ent->schedule == svn_wc_schedule_add))    return svn_error_createf      (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,       _("Failed to mark '%s' absent: item of the same name is already "         "scheduled for addition"),       svn_path_local_style(path, pool));    /* Immediately create an entry for the new item in the parent.  Note     that the parent must already be either added or opened, and thus     it's in an 'incomplete' state just like the new item.  */  tmp_entry.kind = kind;  /* Note that there may already exist a 'ghost' entry in the parent     with the same name, in a 'deleted' state.  If so, it's fine to     overwrite it... but we need to make sure we get rid of the     'deleted' flag when doing so: */  tmp_entry.deleted = FALSE;  /* Post-update processing knows to leave this entry if its revision     is equal to the target revision of the overall update. */  tmp_entry.revision = *(eb->target_revision);  /* And, of course, marking as absent is the whole point. */  tmp_entry.absent = TRUE;  SVN_ERR(svn_wc__entry_modify(adm_access, name, &tmp_entry,                               (SVN_WC__ENTRY_MODIFY_KIND    |                                SVN_WC__ENTRY_MODIFY_REVISION |                                SVN_WC__ENTRY_MODIFY_DELETED |                                SVN_WC__ENTRY_MODIFY_ABSENT),                               TRUE /* immediate write */, pool));  return SVN_NO_ERROR;}static svn_error_t *absent_file(const char *path,            void *parent_baton,            apr_pool_t *pool){  return absent_file_or_dir(path, svn_node_file, parent_baton, pool);}static svn_error_t *absent_directory(const char *path,                 void *parent_baton,                 apr_pool_t *pool){  return absent_file_or_dir(path, svn_node_dir, parent_baton, pool);}/* Common code for add_file() and open_file(). */static svn_error_t *add_or_open_file(const char *path,                 void *parent_baton,                 const char *copyfrom_path,                 svn_revnum_t copyfrom_rev,                 void **file_baton,                 svn_boolean_t adding, /* 0 if replacing */                 apr_pool_t *pool){  struct dir_baton *pb = parent_baton;  struct edit_baton *eb = pb->edit_baton;  struct file_baton *fb;  const svn_wc_entry_t *entry;  svn_node_kind_t kind;  svn_wc_adm_access_t *adm_access;  /* the file_pool can stick around for a *long* time, so we want to use     a subpool for any temporary allocations. */  apr_pool_t *subpool = svn_pool_create(pool);  /* ### kff todo: if file is marked as removed by user, then flag a     conflict in the entry and proceed.  Similarly if it has changed     kind.  see issuezilla task #398. */  fb = make_file_baton(pb, path, adding, pool);  /* It is interesting to note: everything below is just validation. We     aren't actually doing any "work" or fetching any persistent data. */  SVN_ERR(svn_io_check_path(fb->path, &kind, subpool));  SVN_ERR(svn_wc_adm_retrieve(&adm_access, eb->adm_access,                               pb->path, subpool));  SVN_ERR(svn_wc_entry(&entry, fb->path, adm_access, FALSE, subpool));    /* Sanity checks. */  /* If adding, there should be nothing with this name. */  if (adding && (kind != svn_node_none))    return svn_error_createf      (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,       _("Failed to add file '%s': object of the same name already exists"),       svn_path_local_style(fb->path, pool));  /* sussman sez: If we're trying to add a file that's already in     `entries' (but not on disk), that's okay.  It's probably because     the user deleted the working version and ran 'svn up' as a means     of getting the file back.       It certainly doesn't hurt to re-add the file.  We can't possibly     get the entry showing up twice in `entries', since it's a hash;     and we know that we won't lose any local mods.  Let the existing     entry be overwritten.     sussman follows up to himself, many months later: the above     scenario is fine, as long as the pre-existing entry isn't     scheduled for addition.  that's a genuine tree-conflict,     regardless of whether the working file still exists.  */  if (adding && entry && entry->schedule == svn_wc_schedule_add)    return svn_error_createf      (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,       _("Failed to add file '%s': object of the same name is already "         "scheduled for addition"),       svn_path_local_style(fb->path, pool));      /* If replacing, make sure the .svn entry already exists. */  if ((! adding) && (! entry))    return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,                             _("File '%s' in directory '%s' "                               "is not a versioned resource"),                             fb->name,                             svn_path_local_style(pb->path, pool));    /* ### todo:  right now the incoming copyfrom* args are being     completely ignored!  Someday the editor-driver may expect us to     support this optimization;  when that happens, this func needs to     -copy- the specified existing wc file to this location.  From     there, the driver can apply_textdelta on it, etc. */  svn_pool_destroy(subpool);  *file_baton = fb;  return SVN_NO_ERROR;}

⌨️ 快捷键说明

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