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

📄 status.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }  else    {      /* File entries are ... just fine! */      SVN_ERR(send_status_structure(path, adm_access, entry, dir_entry,                                     kind, special, get_all, FALSE,                                    eb->repos_locks, eb->repos_root,                                    status_func, status_baton, pool));    }  return SVN_NO_ERROR;}/* Send svn_wc_status2_t * structures for the directory ADM_ACCESS and   for all its entries through STATUS_FUNC/STATUS_BATON, or, if ENTRY   is non-NULL, only for that directory entry.   PARENT_ENTRY is the entry for the parent of the directory or NULL   if that directory is a working copy root.   If SKIP_THIS_DIR is TRUE (and ENTRY is NULL), the directory's own   status will not be reported.  However, upon recursing, all subdirs   *will* be reported, regardless of this parameter's value.   Other arguments are the same as those passed to   svn_wc_get_status_editor2().  */static svn_error_t *get_dir_status(struct edit_baton *eb,               const svn_wc_entry_t *parent_entry,               svn_wc_adm_access_t *adm_access,               const char *entry,               apr_array_header_t *ignores,               svn_boolean_t descend,               svn_boolean_t get_all,               svn_boolean_t no_ignore,               svn_boolean_t skip_this_dir,               svn_wc_status_func2_t status_func,               void *status_baton,               svn_cancel_func_t cancel_func,               void *cancel_baton,               apr_pool_t *pool){  apr_hash_t *entries;  apr_hash_index_t *hi;  const svn_wc_entry_t *dir_entry;  const char *path = svn_wc_adm_access_path(adm_access);  apr_hash_t *dirents;  apr_array_header_t *patterns = NULL;  apr_pool_t *iterpool, *subpool = svn_pool_create(pool);  /* See if someone wants to cancel this operation. */  if (cancel_func)    SVN_ERR(cancel_func(cancel_baton));  /* Load entries file for the directory into the requested pool. */  SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, subpool));  /* Read PATH's dirents. */  SVN_ERR(svn_io_get_dirents2(&dirents, path, subpool));  /* Get this directory's entry. */  SVN_ERR(svn_wc_entry(&dir_entry, path, adm_access, FALSE, subpool));  /* If "this dir" has "svn:externals" property set on it, store its     name and value in traversal_info.  Also, we want to track the     externals internally so we can report status more accurately. */    {      const svn_string_t *prop_val;      SVN_ERR(svn_wc_prop_get(&prop_val, SVN_PROP_EXTERNALS, path,                               adm_access, subpool));      if (prop_val)        {          apr_array_header_t *ext_items;          int i;          if (eb->traversal_info)            {              apr_pool_t *dup_pool = eb->traversal_info->pool;              const char *dup_path = apr_pstrdup(dup_pool, path);              const char *dup_val = apr_pstrmemdup(dup_pool, prop_val->data,                                                    prop_val->len);              /* First things first -- we put the externals information                 into the "global" traversal info structure. */              apr_hash_set(eb->traversal_info->externals_old,                           dup_path, APR_HASH_KEY_STRING, dup_val);              apr_hash_set(eb->traversal_info->externals_new,                           dup_path, APR_HASH_KEY_STRING, dup_val);            }          /* Now, parse the thing, and copy the parsed results into             our "global" externals hash. */          SVN_ERR(svn_wc_parse_externals_description2(&ext_items, path,                                                      prop_val->data, pool));          for (i = 0; ext_items && i < ext_items->nelts; i++)            {              svn_wc_external_item_t *item;              item = APR_ARRAY_IDX(ext_items, i, svn_wc_external_item_t *);              apr_hash_set(eb->externals, svn_path_join(path,                                                        item->target_dir,                                                        pool),                           APR_HASH_KEY_STRING, item);            }        }    }  /* Early out -- our caller only cares about a single ENTRY in this     directory.  */  if (entry)    {      const svn_wc_entry_t *entry_entry;      svn_io_dirent_t* dirent_p = apr_hash_get(dirents, entry,                                               APR_HASH_KEY_STRING);      entry_entry = apr_hash_get(entries, entry, APR_HASH_KEY_STRING);      /* If ENTRY is versioned, send its versioned status. */      if (entry_entry)        {          SVN_ERR(handle_dir_entry(eb, adm_access, entry, dir_entry,                                    entry_entry,                                   dirent_p ? dirent_p->kind : svn_node_none,                                   dirent_p ? dirent_p->special : FALSE,                                   ignores, descend, get_all,                                    no_ignore, status_func, status_baton,                                    cancel_func, cancel_baton, subpool));        }      /* Otherwise, if it exists, send its unversioned status. */      else if (dirent_p)        {          if (ignores && ! patterns)            SVN_ERR(collect_ignore_patterns(&patterns, ignores,                                             adm_access, subpool));          SVN_ERR(send_unversioned_item(entry, dirent_p->kind,                                        dirent_p->special, adm_access,                                         patterns, eb->externals, no_ignore,                                        eb->repos_locks, eb->repos_root,                                        status_func, status_baton, subpool));        }      /* Regardless, we're done here.  Let's go home. */      return SVN_NO_ERROR;    }  /** If we get here, ENTRY is NULL and we are handling all the      directory entries. */  /* Make our iteration pool. */  iterpool = svn_pool_create(subpool);  /* Add empty status structures for each of the unversioned things. */  for (hi = apr_hash_first(subpool, dirents); hi; hi = apr_hash_next(hi))    {      const void *key;      apr_ssize_t klen;      void *val;      svn_io_dirent_t *dirent_p;      apr_hash_this(hi, &key, &klen, &val);              /* Skip versioned things, and skip the administrative         directory. */      if (apr_hash_get(entries, key, klen)          || svn_wc_is_adm_dir(key, subpool))        continue;      svn_pool_clear(iterpool);      if (ignores && ! patterns)        SVN_ERR(collect_ignore_patterns(&patterns, ignores,                                         adm_access, subpool));      /* Make an unversioned status item for KEY, and put it into our         return hash. */      dirent_p = val;      SVN_ERR(send_unversioned_item(key, dirent_p->kind, dirent_p->special,                                    adm_access,                                     patterns, eb->externals, no_ignore,                                    eb->repos_locks, eb->repos_root,                                    status_func, status_baton, iterpool));    }  /* Handle "this-dir" first. */  if (! skip_this_dir)    SVN_ERR(send_status_structure(path, adm_access, dir_entry,                                   parent_entry, svn_node_dir, FALSE,                                  get_all, FALSE, eb->repos_locks,                                  eb->repos_root, status_func, status_baton,                                  subpool));  /* Loop over entries hash */  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))    {      const void *key;      void *val;      svn_io_dirent_t *dirent_p;      /* Get the next entry */      apr_hash_this(hi, &key, NULL, &val);      dirent_p = apr_hash_get(dirents, key, APR_HASH_KEY_STRING);      /* ### todo: What if the subdir is from another repository? */                /* Skip "this-dir". */      if (strcmp(key, SVN_WC_ENTRY_THIS_DIR) == 0)        continue;      /* Clear the iteration subpool. */      svn_pool_clear(iterpool);      /* Handle this directory entry (possibly recursing). */      SVN_ERR(handle_dir_entry(eb, adm_access, key, dir_entry, val,                               dirent_p ? dirent_p->kind : svn_node_none,                               dirent_p ? dirent_p->special : FALSE,                               ignores,                                descend, get_all, no_ignore,                                status_func, status_baton, cancel_func,                                cancel_baton, iterpool));    }    /* Destroy our subpools. */  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/*** Helpers ***//* A faux status callback function for stashing STATUS item in an hash   (which is the BATON), keyed on PATH.  This implements the   svn_wc_status_func2_t interface. */static voidhash_stash(void *baton,           const char *path,           svn_wc_status2_t *status){  apr_hash_t *stat_hash = baton;  apr_pool_t *hash_pool = apr_hash_pool_get(stat_hash);  assert(! apr_hash_get(stat_hash, path, APR_HASH_KEY_STRING));  apr_hash_set(stat_hash, apr_pstrdup(hash_pool, path),                APR_HASH_KEY_STRING, svn_wc_dup_status2(status, hash_pool));}/* Look up the key PATH in BATON->STATII.  IS_DIR_BATON indicates whether   baton is a struct *dir_baton or struct *file_baton.  If the value doesn't   yet exist, and the REPOS_TEXT_STATUS indicates that this is an   addition, create a new status struct using the hash's pool.  Merge   REPOS_TEXT_STATUS and REPOS_PROP_STATUS into the status structure's   "network" fields.   If a new struct was added, set the repos_lock to REPOS_LOCK. */static svn_error_t *tweak_statushash(void *baton,                 svn_boolean_t is_dir_baton,                 svn_wc_adm_access_t *adm_access,                 const char *path,                 svn_boolean_t is_dir,                 enum svn_wc_status_kind repos_text_status,                 enum svn_wc_status_kind repos_prop_status,                 svn_lock_t *repos_lock){  svn_wc_status2_t *statstruct;  apr_pool_t *pool;  apr_hash_t *statushash;  if (is_dir_baton)    statushash = ((struct dir_baton *) baton)->statii;  else    statushash = ((struct file_baton *) baton)->dir_baton->statii;  pool = apr_hash_pool_get(statushash);  /* Is PATH already a hash-key? */  statstruct = apr_hash_get(statushash, path, APR_HASH_KEY_STRING);  /* If not, make it so. */  if (! statstruct)    {      /* If this item isn't being added, then we're most likely         dealing with a non-recursive (or at least partially         non-recursive) working copy.  Due to bugs in how the client         reports the state of non-recursive working copies, the         repository can send back responses about paths that don't         even exist locally.  Our best course here is just to ignore         those responses.  After all, if the client had reported         correctly in the first, that path would either be mentioned         as an 'add' or not mentioned at all, depending on how we         eventually fix the bugs in non-recursivity.  See issue         #2122 for details. */      if (repos_text_status != svn_wc_status_added)        return SVN_NO_ERROR;      /* Use the public API to get a statstruct, and put it into the hash. */      SVN_ERR(svn_wc_status2(&statstruct, path, adm_access, pool));      statstruct->repos_lock = repos_lock;      apr_hash_set(statushash, apr_pstrdup(pool, path),                    APR_HASH_KEY_STRING, statstruct);    }  /* Merge a repos "delete" + "add" into a single "replace". */  if ((repos_text_status == svn_wc_status_added)      && (statstruct->repos_text_status == svn_wc_status_deleted))    repos_text_status = svn_wc_status_replaced;  /* Tweak the structure's repos fields. */  if (repos_text_status)    statstruct->repos_text_status = repos_text_status;  if (repos_prop_status)    statstruct->repos_prop_status = repos_prop_status;    /* Copy out of date info. */  if (is_dir_baton)    {      struct dir_baton *b = baton;      if (b->url)        statstruct->url = apr_pstrdup(pool, b->url);      statstruct->ood_kind = b->ood_kind;      /* The last committed rev, date, and author for deleted items         isn't available. */      if (statstruct->repos_text_status != svn_wc_status_deleted)        {          statstruct->ood_last_cmt_rev = b->ood_last_cmt_rev;          statstruct->ood_last_cmt_date = b->ood_last_cmt_date;          if (b->ood_last_cmt_author)            statstruct->ood_last_cmt_author =              apr_pstrdup(pool, b->ood_last_cmt_author);        }    }  else    {      struct file_baton *b = baton;      if (b->url)        statstruct->url = apr_pstrdup(pool, b->url);      statstruct->ood_last_cmt_rev = b->ood_last_cmt_rev;      statstruct->ood_last_cmt_date = b->ood_last_cmt_date;      statstruct->ood_kind = b->ood_kind;      if (b->ood_last_cmt_author)        statstruct->ood_last_cmt_author =          apr_pstrdup(pool, b->ood_last_cmt_author);    }  return SVN_NO_ERROR;}/* Returns the URL for DB, or NULL: */static const char *find_dir_url(const struct dir_baton *db, apr_pool_t *pool){  /* If we have no name, we're the root, return the anchor URL. */  if (! db->name)    return db->edit_baton->anchor_status->entry->url;  else    {      const char *url;      struct dir_baton *pb = db->parent_baton;      svn_wc_status2_t *status = apr_hash_get(pb->statii, db->name,                                              APR_HASH_KEY_STRING);      /* Note that status->entry->url is NULL in the case of a missing       * directory, which means we need to recurse up another level to       * get a useful URL. */      if (status && status->entry && status->entry->url)        return status->entry->url;      url = find_dir_url(pb, pool);      if (url)        return svn_path_url_add_component(url, db->name, pool);      else        return NULL;    }}

⌨️ 快捷键说明

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