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

📄 props.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      SVN_ERR(svn_wc__prop_path(&working_prop_tmp_path, full_path,                                kind, TRUE, pool));      /* Write the working prop hash to path/.svn/tmp/props/name or         path/.svn/tmp/dir-props */      SVN_ERR(svn_wc__save_prop_file(working_prop_tmp_path, working_props,                                     pool));        /* Compute pathnames for the "mv" log entries.  Notice that these         paths are RELATIVE pathnames (each beginning with ".svn/"), so         that each .svn subdir remains separable when executing run_log().  */      tmp_props = apr_pstrdup(pool, working_prop_tmp_path + access_len);        /* Write log entry to move working tmp copy to real working area. */      SVN_ERR(svn_wc__loggy_move(log_accum, NULL,                                 adm_access, tmp_props, real_props,                                 FALSE, pool));      /* Make props read-only */      SVN_ERR(svn_wc__loggy_set_readonly(log_accum, adm_access,                                         real_props, pool));    }  else    {      /* No property modifications, remove the file instead. */      SVN_ERR(svn_wc__loggy_remove(log_accum, adm_access, real_props, pool));    }  /* Repeat the above steps for the base properties if required. */  if (write_base_props)    {      const char *base_propfile_path, *base_prop_tmp_path;      const char *tmp_prop_base, *real_prop_base;      SVN_ERR(svn_wc__prop_base_path(&base_propfile_path, full_path,                                     kind, FALSE, pool));      real_prop_base = apr_pstrdup(pool, base_propfile_path + access_len);      if (apr_hash_count(base_props) > 0)        {          SVN_ERR(svn_wc__prop_base_path(&base_prop_tmp_path, full_path,                                         kind, TRUE, pool));          SVN_ERR(svn_wc__save_prop_file(base_prop_tmp_path, base_props,                                         pool));          tmp_prop_base = apr_pstrdup(pool, base_prop_tmp_path + access_len);          SVN_ERR(svn_wc__loggy_move(log_accum, NULL, adm_access,                                     tmp_prop_base, real_prop_base,                                     FALSE, pool));          SVN_ERR(svn_wc__loggy_set_readonly(log_accum, adm_access,                                             real_prop_base, pool));        }      else        SVN_ERR(svn_wc__loggy_remove(log_accum, adm_access, real_prop_base,                                     pool));    }  return SVN_NO_ERROR;}/*---------------------------------------------------------------------*//*** Merging propchanges into the working copy ***/svn_error_t *svn_wc_merge_props(svn_wc_notify_state_t *state,                   const char *path,                   svn_wc_adm_access_t *adm_access,                   apr_hash_t *baseprops,                   const apr_array_header_t *propchanges,                   svn_boolean_t base_merge,                   svn_boolean_t dry_run,                   apr_pool_t *pool){  const svn_wc_entry_t *entry;  const char *parent, *base_name;  svn_stringbuf_t *log_accum;  /* IMPORTANT: svn_wc_merge_prop_diffs relies on the fact that baseprops     may be NULL. */  SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));  if (entry == NULL)    return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,                             _("'%s' is not under version control"),                             svn_path_local_style(path, pool));  /* Notice that we're not using svn_path_split_if_file(), because     that looks at the actual working file.  Its existence shouldn't     matter, so we're looking at entry->kind instead. */  switch (entry->kind)    {    case svn_node_dir:      parent = path;      base_name = NULL;      break;    case svn_node_file:      svn_path_split(path, &parent, &base_name, pool);      break;    default:      return SVN_NO_ERROR; /* ### svn_node_none or svn_node_unknown */    }  if (! dry_run)    log_accum = svn_stringbuf_create("", pool);    /* Note that while this routine does the "real" work, it's only     prepping tempfiles and writing log commands.  */  SVN_ERR(svn_wc__merge_props(state, adm_access, base_name, baseprops,                              propchanges, base_merge, dry_run,                              pool, &log_accum));  if (! dry_run)    {      SVN_ERR(svn_wc__write_log(adm_access, 0, log_accum, pool));      SVN_ERR(svn_wc__run_log(adm_access, NULL, pool));    }  return SVN_NO_ERROR;}svn_error_t *svn_wc__merge_props(svn_wc_notify_state_t *state,                    svn_wc_adm_access_t *adm_access,                    const char *name,                    apr_hash_t *server_baseprops,                    const apr_array_header_t *propchanges,                    svn_boolean_t base_merge,                    svn_boolean_t dry_run,                    apr_pool_t *pool,                    svn_stringbuf_t **entry_accum){  int i;  svn_boolean_t is_dir;  const char *entryname;  const char *full_path;  apr_hash_t *working_props;   /* all `working' properties */  apr_hash_t *base_props;    /* all `pristine' properties */    const char *access_path = svn_wc_adm_access_path(adm_access);  int access_len = strlen(access_path);  const char *reject_path = NULL;  apr_file_t *reject_tmp_fp = NULL;       /* the temporary conflicts file */  const char *reject_tmp_path = NULL;  /* Non-empty path without trailing slash need an extra slash removed */  if (access_len != 0 && access_path[access_len - 1] != '/')    access_len++;  if (name == NULL)    {      /* We must be merging props on the directory PATH  */      entryname = SVN_WC_ENTRY_THIS_DIR;      full_path = access_path;      is_dir = TRUE;    }  else    {      /* We must be merging props on the file PATH/NAME */      entryname = name;      full_path = svn_path_join(access_path, name, pool);      is_dir = FALSE;    }  /* Load the base & working property files into hashes */  SVN_ERR(svn_wc__load_props(&base_props, &working_props,                             adm_access, entryname, pool));  if (!server_baseprops)    server_baseprops = base_props;  if (state)    {      /* Start out assuming no conflicts.  Don't bother to examine         propchanges->nelts yet; even if we knew there were         propchanges, we wouldn't yet know if they are "normal" props,         as opposed wc or entry props.  */       if (propchanges->nelts > 0)        *state = svn_wc_notify_state_changed;      else        *state = svn_wc_notify_state_unchanged;    }  /* Looping over the array of incoming propchanges we want to apply: */  for (i = 0; i < propchanges->nelts; i++)    {      const char *propname;      svn_string_t *conflict = NULL;      const svn_prop_t *incoming_change;      const svn_string_t *from_val, *to_val, *working_val;      svn_boolean_t is_normal;      /* For the incoming propchange, figure out the TO and FROM values. */      incoming_change = &APR_ARRAY_IDX(propchanges, i, svn_prop_t);      propname = incoming_change->name;      is_normal = svn_wc_is_normal_prop(propname);      to_val = incoming_change->value         ? svn_string_dup(incoming_change->value, pool) : NULL;      from_val = apr_hash_get(server_baseprops, propname, APR_HASH_KEY_STRING);                      working_val = apr_hash_get(working_props, propname, APR_HASH_KEY_STRING);      if (base_merge)        apr_hash_set(base_props, propname, APR_HASH_KEY_STRING, to_val);            /* We already know that state is at least `modified', so mark         that, but remember that we may later upgrade to `merged' or         even `conflicted'. */      if (state && is_normal)        *state = svn_wc_notify_state_changed;      if (! from_val)  /* adding a new property */        {          if (working_val)             {              /* the property already exists in working_props... */                            if (svn_string_compare(working_val, to_val))                {                  /* The value we want is already there, so it's a                     'clean merge'. */                  if (state && is_normal                      && (*state != svn_wc_notify_state_conflicted))                    *state = svn_wc_notify_state_merged;                }              else                {                  conflict =                    svn_string_createf                     (pool,                      _("Trying to add new property '%s' with value '%s',\n"                       "but property already exists with value '%s'."),                     propname, to_val->data, working_val->data);                }            }                    else  /* property dosen't yet exist in working_props...  */            {              /* so just set it */              apr_hash_set(working_props, propname,                           APR_HASH_KEY_STRING, to_val);            }        }            else  /* changing or deleting an existing property */        {          if (! working_val)  /* ... but it's not in the working_props */            {              if (to_val)                {                  conflict =                    svn_string_createf                     (pool,                      _("Trying to change property '%s' from '%s' to '%s',\n"                       "but the property does not exist."),                     propname, from_val->data, to_val->data);                }              else                {                  /* The property to be deleted doesn't exist, so it's                     a 'clean merge'. */                  if (state && is_normal                      && (*state != svn_wc_notify_state_conflicted))                    *state = svn_wc_notify_state_merged;                }            }                    else  /* property already exists */            {              if (svn_string_compare(working_val, from_val))                {                  /* property has the expected 'from' value, so it's                     fine to set it to the 'to' value.  */                  apr_hash_set(working_props, propname,                               APR_HASH_KEY_STRING, to_val);                }              else if (!to_val && !svn_string_compare(from_val, working_val))                {                  conflict =                    svn_string_createf                    (pool, _("Trying to delete property '%s' but value"                             " has been modified from '%s' to '%s'."),                     propname, from_val->data, working_val->data);                }              else if (svn_string_compare(working_val, to_val))                {                  /* The value we want is already there, so it's a                     'clean merge'. */                  if (state && is_normal                      && (*state != svn_wc_notify_state_conflicted))                    *state = svn_wc_notify_state_merged;                }              else /* property has some random value */                {                  conflict =                    svn_string_createf                     (pool,                      _("Trying to change property '%s' from '%s' to '%s',\n"                       "but property already exists with value '%s'."),                     propname, from_val->data, to_val->data, working_val->data);                }            }        }      /* merging logic complete, now we need to possibly log conflict         data to tmpfiles.  */            if (conflict)        {          if (state && is_normal)            *state = svn_wc_notify_state_conflicted;                    if (dry_run)            continue;   /* skip to next incoming change */                    if (! reject_tmp_fp)            /* This is the very first prop conflict found on this item. */            SVN_ERR(open_reject_tmp_file(&reject_tmp_fp, &reject_tmp_path,                                         full_path, adm_access, is_dir,                                         pool));                    /* Append the conflict to the open tmp/PROPS/---.prej file */          SVN_ERR(append_prop_conflict(reject_tmp_fp, conflict, pool));        }    }  /* foreach propchange ... */  /* Finished applying all incoming propchanges to our hashes! */    if (dry_run)    return SVN_NO_ERROR;  SVN_ERR(svn_wc__install_props(entry_accum, adm_access, entryname,                                base_props, working_props, base_merge,                                pool));  if (reject_tmp_fp)    {      /* There's a .prej file sitting in .svn/tmp/ somewhere.  Deal         with the conflicts.  */      /* First, _close_ this temporary conflicts file.  We've been         appending to it all along. */      SVN_ERR(svn_io_file_close(reject_tmp_fp, pool));                                        /* Now try to get the name of a pre-existing .prej file from the         entries file */      SVN_ERR(get_existing_prop_reject_file(&reject_path,                                            adm_access,                                            entryname,                                            pool));      if (! reject_path)        {          /* Reserve a new .prej file *above* the .svn/ directory by             opening and closing it. */          const char *reserved_path;          const char *full_reject_path;          full_reject_path = svn_path_join             (access_path, is_dir ? SVN_WC__THIS_DIR_PREJ : name, pool);          SVN_ERR(svn_io_open_unique_file2(NULL, &reserved_path,                                           full_reject_path,                                           SVN_WC__PROP_REJ_EXT,                                           svn_io_file_del_none, pool));          /* This file will be overwritten when the log is run; that's             ok, because at least now we have a reservation on             disk. */          /* Now just get the name of the reserved file.  This is the             "relative" path we will use in the log entry. */          reject_path = svn_path_basename(reserved_path, pool);        }      /* We've now guaranteed that some kind of .prej file exists         above the .svn/ dir.  We write log entries to append our         conflicts to it. */      SVN_ERR(svn_wc__loggy_append(entry_accum, adm_access,                                   reject_tmp_path, reject_path, pool));

⌨️ 快捷键说明

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