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

📄 commit_util.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      if (entry->kind == svn_node_file)        {          /* Check for text mods.  If EOL_PROP_CHANGED is TRUE, then             we need to force a translated byte-for-byte comparison             against the text-base so that a timestamp comparison             won't bail out early.  Depending on how the svn:eol-style             prop was changed, we might have to send new text to the             server to match the new newline style.  */          if (state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)            SVN_ERR(svn_wc_text_modified_p(&text_mod, path,                                           eol_prop_changed, adm_access,                                           pool));          else            text_mod = TRUE;        }    }  /* Else, if we aren't deleting this item, we'll have to look for     local text or property mods to determine if the path might be     committable. */  else if (! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))    {      svn_boolean_t eol_prop_changed;      /* See if there are property modifications to send. */      SVN_ERR(check_prop_mods(&prop_mod, &eol_prop_changed, path,                               adm_access, pool));      /* Check for text mods on files.  If EOL_PROP_CHANGED is TRUE,         then we need to force a translated byte-for-byte comparison         against the text-base so that a timestamp comparison won't         bail out early.  Depending on how the svn:eol-style prop was         changed, we might have to send new text to the server to         match the new newline style.  */      if (entry->kind == svn_node_file)        SVN_ERR(svn_wc_text_modified_p(&text_mod, path, eol_prop_changed,                                       adm_access, pool));    }  /* Set text/prop modification flags accordingly. */  if (text_mod)    state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;  if (prop_mod)    state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;  /* If the entry has a lock token and it is already a commit candidate,     or the caller wants unmodified locked items to be treated as     such, note this fact. */  if (entry->lock_token      && (state_flags || just_locked))    state_flags |= SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN;  /* Now, if this is something to commit, add it to our list. */  if (state_flags)    {      /* Finally, add the committable item. */      add_committable(committables, path, entry->kind, url,                      entry->revision,                      cf_url,                      cf_rev,                      state_flags);      if (lock_tokens && entry->lock_token)        apr_hash_set(lock_tokens, apr_pstrdup(token_pool, url),                     APR_HASH_KEY_STRING,                     apr_pstrdup(token_pool, entry->lock_token));    }  /* For directories, recursively handle each of their entries (except     when the directory is being deleted, unless the deletion is part     of a replacement ... how confusing).  Oh, and don't recurse at     all if this is a nonrecursive commit.  ### We'll probably make     the whole 'nonrecursive' concept go away soon and be replaced     with the more sophisticated Depth0|Depth1|DepthInfinity. */  if (entries && (! nonrecursive)      && ((! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))          || (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)))    {      apr_hash_index_t *hi;      const svn_wc_entry_t *this_entry;      apr_pool_t *loop_pool = svn_pool_create(pool);      /* Loop over all other entries in this directory, skipping the         "this dir" entry. */      for (hi = apr_hash_first(pool, entries);           hi;           hi = apr_hash_next(hi))        {          const void *key;          void *val;          const char *name;          const char *full_path;          const char *used_url = NULL;          const char *name_uri = NULL;          const char *this_cf_url = cf_url ? cf_url : copyfrom_url;          svn_wc_adm_access_t *dir_access = adm_access;          svn_pool_clear(loop_pool);          /* Get the next entry.  Name is an entry name; value is an             entry structure. */          apr_hash_this(hi, &key, NULL, &val);          name = key;                    /* Skip "this dir" */          if (! strcmp(name, SVN_WC_ENTRY_THIS_DIR))            continue;          this_entry = val;          name_uri = svn_path_uri_encode(name, loop_pool);          full_path = svn_path_join(path, name, loop_pool);          if (this_cf_url)            this_cf_url = svn_path_join(this_cf_url, name_uri, loop_pool);          /* We'll use the entry's URL if it has one and if we aren't             in copy_mode, else, we'll just extend the parent's URL             with the entry's basename.  */          if ((! this_entry->url) || (copy_mode))            used_url = svn_path_join(url, name_uri, loop_pool);          /* Recurse. */          if (this_entry->kind == svn_node_dir)            {              svn_error_t *lockerr;              lockerr = svn_wc_adm_retrieve(&dir_access, adm_access,                                            full_path, loop_pool);              if (lockerr)                {                  if (lockerr->apr_err == SVN_ERR_WC_NOT_LOCKED)                    {                      /* A missing, schedule-delete child dir is                         allowable.  Just don't try to recurse. */                      svn_node_kind_t childkind;                      svn_error_t *err = svn_io_check_path(full_path,                                                           &childkind,                                                           loop_pool);                      if (! err                          && childkind == svn_node_none                          && this_entry->schedule == svn_wc_schedule_delete)                        {                          add_committable(committables, full_path,                                          this_entry->kind, used_url,                                          SVN_INVALID_REVNUM,                                           NULL,                                          SVN_INVALID_REVNUM,                                          SVN_CLIENT_COMMIT_ITEM_DELETE);                          svn_error_clear(lockerr);                          continue; /* don't recurse! */                        }                      else                        {                          svn_error_clear(err);                          return lockerr;                        }                    }                  else                    return lockerr;                }            }          else            dir_access = adm_access;          SVN_ERR(harvest_committables                   (committables, lock_tokens, full_path, dir_access,                   used_url ? used_url : this_entry->url,                   this_cf_url,                   this_entry,                   entry,                   adds_only,                   copy_mode,                   FALSE, just_locked,                   ctx,                   loop_pool));        }      svn_pool_destroy(loop_pool);    }  /* Fetch lock tokens for descendants of deleted directories. */  if (lock_tokens && entry->kind == svn_node_dir      && (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))    {      SVN_ERR(svn_wc_walk_entries2(path, adm_access, &add_tokens_callbacks,                                   lock_tokens, FALSE, ctx->cancel_func,                                   ctx->cancel_baton, pool));    }  return SVN_NO_ERROR;}svn_error_t *svn_client__harvest_committables(apr_hash_t **committables,                                 apr_hash_t **lock_tokens,                                 svn_wc_adm_access_t *parent_dir,                                 apr_array_header_t *targets,                                 svn_boolean_t nonrecursive,                                 svn_boolean_t just_locked,                                 svn_client_ctx_t *ctx,                                 apr_pool_t *pool){  int i = 0;  svn_wc_adm_access_t *dir_access;  apr_pool_t *subpool = svn_pool_create(pool);  /* It's possible that one of the named targets has a parent that is   * itself scheduled for addition or replacement -- that is, the   * parent is not yet versioned in the repository.  This is okay, as   * long as the parent itself is part of this same commit, either   * directly, or by virtue of a grandparent, great-grandparent, etc,   * being part of the commit.   *   * Since we don't know what's included in the commit until we've   * harvested all the targets, we can't reliably check this as we   * go.  So in `danglers', we record named targets whose parents   * are unversioned, then after harvesting the total commit group, we   * check to make sure those parents are included.   *   * Each key of danglers is an unversioned parent.  The (const char *)    * value is one of that parent's children which is named as part of   * the commit; the child is included only to make a better error   * message.   *   * (The reason we don't bother to check unnamed -- i.e, implicit --   * targets is that they can only join the commit if their parents   * did too, so this situation can't arise for them.)   */  apr_hash_t *danglers = apr_hash_make(pool);  /* Create the COMMITTABLES hash. */  *committables = apr_hash_make(pool);  /* And the LOCK_TOKENS dito. */  *lock_tokens = apr_hash_make(pool);  do    {      svn_wc_adm_access_t *adm_access;      const svn_wc_entry_t *entry;      const char *target;      svn_pool_clear(subpool);      /* Add the relative portion of our full path (if there are no         relative paths, TARGET will just be PARENT_DIR for a single         iteration. */      target = svn_path_join_many(subpool,                                   svn_wc_adm_access_path(parent_dir),                                    targets->nelts                                   ? (((const char **) targets->elts)[i])                                   : NULL,                                  NULL);      /* No entry?  This TARGET isn't even under version control! */      SVN_ERR(svn_wc_adm_probe_retrieve(&adm_access, parent_dir,                                        target, subpool));      SVN_ERR(svn_wc_entry(&entry, target, adm_access, FALSE, subpool));      if (! entry)        return svn_error_createf          (SVN_ERR_ENTRY_NOT_FOUND, NULL,           _("'%s' is not under version control"), target);      if (! entry->url)        return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,                                  _("Entry for '%s' has no URL"),                                 svn_path_local_style(target, pool));      /* We have to be especially careful around entries scheduled for         addition or replacement. */      if ((entry->schedule == svn_wc_schedule_add)          || (entry->schedule == svn_wc_schedule_replace))        {          const char *parent, *base_name;          svn_wc_adm_access_t *parent_access;          const svn_wc_entry_t *p_entry = NULL;          svn_error_t *err;          svn_path_split(target, &parent, &base_name, subpool);          err = svn_wc_adm_retrieve(&parent_access, parent_dir,                                     parent, subpool);          if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)            {              svn_error_clear(err);              SVN_ERR(svn_wc_adm_open3(&parent_access, NULL, parent,                                       FALSE, 0, ctx->cancel_func,                                       ctx->cancel_baton, subpool));            }          else if (err)            {              return err;            }          SVN_ERR(svn_wc_entry(&p_entry, parent, parent_access,                                FALSE, subpool));          if (! p_entry)            return svn_error_createf               (SVN_ERR_WC_CORRUPT, NULL,                _("'%s' is scheduled for addition within unversioned parent"),               svn_path_local_style(target, pool));          if ((p_entry->schedule == svn_wc_schedule_add)              || (p_entry->schedule == svn_wc_schedule_replace))            {              /* Copy the parent and target into pool; subpool                 lasts only for this loop iteration, and we check                 danglers after the loop is over. */              apr_hash_set(danglers, apr_pstrdup(pool, parent),                           APR_HASH_KEY_STRING,                            apr_pstrdup(pool, target));            }        }            /* If this entry is marked as 'copied' but scheduled normally, then         it should be the child of something else marked for addition with         history. */      if ((entry->copied) && (entry->schedule == svn_wc_schedule_normal))        return svn_error_createf           (SVN_ERR_ILLEGAL_TARGET, NULL,            _("Entry for '%s' is marked as 'copied' but is not itself scheduled"             "\nfor addition.  Perhaps you're committing a target that is\n"             "inside an unversioned (or not-yet-versioned) directory?"),           svn_path_local_style(target, pool));      /* Handle our TARGET. */      SVN_ERR(svn_wc_adm_retrieve(&dir_access, parent_dir,                                  (entry->kind == svn_node_dir                                   ? target                                   : svn_path_dirname(target, subpool)),                                  subpool));      SVN_ERR(harvest_committables(*committables, *lock_tokens, target, dir_access,                                   entry->url, NULL, entry, NULL, FALSE,                                    FALSE, nonrecursive, just_locked, ctx,                                   subpool));      i++;    }  while (i < targets->nelts);  /* Make sure that every path in danglers is part of the commit. */  {    apr_hash_index_t *hi;    for (hi = apr_hash_first(pool, danglers); hi; hi = apr_hash_next(hi))      {        const void *key;        void *val;        const char *dangling_parent, *dangling_child;        /* Get the next entry.  Name is an entry name; value is an           entry structure. */        apr_hash_this(hi, &key, NULL, &val);        dangling_parent = key;        dangling_child = val;        if (! look_up_committable(*committables, dangling_parent, pool))          {            return svn_error_createf               (SVN_ERR_ILLEGAL_TARGET, NULL,                _("'%s' is not under version control "                 "and is not part of the commit, "                 "yet its child '%s' is part of the commit"),               /* Probably one or both of these is an entry, but                  safest to local_stylize just in case. */               svn_path_local_style(dangling_parent, pool),               svn_path_local_style(dangling_child, pool));          }      }  }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}svn_error_t *svn_client__get_copy_committables(apr_hash_t **committables,                                  const char *new_url,                                  const char *target,                                  svn_wc_adm_access_t *adm_access,                                  svn_client_ctx_t *ctx,                                  apr_pool_t *pool){  const svn_wc_entry_t *entry;  /* Create the COMMITTABLES hash. */  *committables = apr_hash_make(pool);  /* Read the entry for TARGET. */  SVN_ERR(svn_wc_entry(&entry, target, adm_access, FALSE, pool));  if (! entry)    return svn_error_createf      (SVN_ERR_ENTRY_NOT_FOUND, NULL, _("'%s' is not under version control"),       svn_path_local_style(target, pool));        /* Handle our TARGET. */  SVN_ERR(harvest_committables(*committables, NULL, target,                               adm_access, new_url, entry->url, entry, NULL,                               FALSE, TRUE, FALSE, FALSE, ctx, pool));  return SVN_NO_ERROR;}int svn_client__sort_commit_item_urls(const void *a, const void *b){  const svn_client_commit_item2_t *item1    = *((const svn_client_commit_item2_t * const *) a);  const svn_client_commit_item2_t *item2    = *((const svn_client_commit_item2_t * const *) b);  return svn_path_compare_paths(item1->url, item2->url);}svn_error_t *svn_client__condense_commit_items(const char **base_url,                                  apr_array_header_t *commit_items,                                  apr_pool_t *pool){  apr_array_header_t *ci = commit_items; /* convenience */  const char *url;  svn_client_commit_item2_t *item, *last_item = NULL;  int i;    assert(ci && ci->nelts);

⌨️ 快捷键说明

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