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

📄 status.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If the item is ignored, and we don't want ignores, skip it. */
  if ((status->text_status == svn_wc_status_ignored) && (! eb->no_ignore))
    return FALSE;

  /* If we want everything, we obviously want this single-item subset
     of everything. */
  if (eb->get_all)
    return TRUE;

  /* If the item is unversioned, display it. */
  if (status->text_status == svn_wc_status_unversioned)
    return TRUE;

  /* If the text or property states are interesting, send it. */
  if ((status->text_status != svn_wc_status_none)
      && (status->text_status != svn_wc_status_normal))
    return TRUE;
  if ((status->prop_status != svn_wc_status_none)
      && (status->prop_status != svn_wc_status_normal))
    return TRUE;

  /* If it's locked or switched, send it. */
  if (status->locked)
    return TRUE;
  if (status->switched)
    return TRUE;

  /* Otherwise, don't send it. */
  return FALSE;
}


/* Baton for mark_status. */
struct status_baton
{
  svn_wc_status_func_t real_status_func;   /* real status function */
  void *real_status_baton;                 /* real status baton */
};

/* A status callback function which wraps the *real* status
   function/baton.   It simply sets the "repos_text_status" field of the
   STATUS to svn_wc_status_deleted and passes it off to the real
   status func/baton. */
static void
mark_deleted (void *baton,
              const char *path,
              svn_wc_status_t *status)
{
  struct status_baton *sb = baton;
  status->repos_text_status = svn_wc_status_deleted;
  sb->real_status_func (sb->real_status_baton, path, status);
}


/* Handle a directory's STATII hash.  EB is the edit baton.  DIR_PATH
   and DIR_ENTRY are the on-disk path and entry, respectively, for the
   directory itself.  If DESCEND is set, this function will recurse
   into subdirectories.  Also, if DIR_WAS_DELETED is set, each status
   that is reported through this function will have its
   repos_text_status field showing a deletion.  Use POOL for all
   allocations. */
static svn_error_t *
handle_statii (struct edit_baton *eb,
               svn_wc_entry_t *dir_entry,
               const char *dir_path,
               apr_hash_t *statii,
               svn_boolean_t dir_was_deleted,
               svn_boolean_t descend,
               apr_pool_t *pool)
{
  apr_array_header_t *ignores = eb->ignores;
  apr_hash_index_t *hi; 
  apr_pool_t *subpool = svn_pool_create (pool);
  svn_wc_status_func_t status_func = eb->status_func;
  void *status_baton = eb->status_baton;
  struct status_baton sb;

  if (dir_was_deleted)
    {
      sb.real_status_func = eb->status_func;
      sb.real_status_baton = eb->status_baton;
      status_func = mark_deleted;
      status_baton = &sb;
    }

  /* Loop over all the statuses still in our hash, handling each one. */
  for (hi = apr_hash_first (pool, statii); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      void *val;
      svn_wc_status_t *status;

      apr_hash_this (hi, &key, NULL, &val);
      status = val;

      /* Clear the subpool. */
      svn_pool_clear (subpool);

      /* Now, handle the status. */
      if (svn_wc__adm_missing (eb->adm_access, key))
        status->text_status = svn_wc_status_missing;
      else if (descend && status->entry && status->entry->kind == svn_node_dir)
        {
          svn_wc_adm_access_t *dir_access;
          SVN_ERR (svn_wc_adm_retrieve (&dir_access, eb->adm_access,
                                        key, subpool));
          SVN_ERR (get_dir_status (eb, dir_entry, dir_access, NULL,
                                   ignores, TRUE, eb->get_all, 
                                   eb->no_ignore, TRUE, status_func, 
                                   status_baton, eb->cancel_func, 
                                   eb->cancel_baton, subpool));
        }
      if (dir_was_deleted)
        status->repos_text_status = svn_wc_status_deleted;
      if (is_sendable_status (status, eb))
        (eb->status_func)(eb->status_baton, key, status);
    }
    
  /* Destroy the subpool. */
  svn_pool_destroy (subpool);

  return SVN_NO_ERROR;
}


/*----------------------------------------------------------------------*/

/*** The callbacks we'll plug into an svn_delta_editor_t structure. ***/

static svn_error_t *
set_target_revision (void *edit_baton, 
                     svn_revnum_t target_revision,
                     apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;
  *(eb->target_revision) = target_revision;
  return SVN_NO_ERROR;
}


static svn_error_t *
open_root (void *edit_baton,
           svn_revnum_t base_revision,
           apr_pool_t *pool,
           void **dir_baton)
{
  struct edit_baton *eb = edit_baton;
  eb->root_opened = TRUE;
  return make_dir_baton (dir_baton, NULL, eb, NULL, pool);
}


static svn_error_t *
delete_entry (const char *path,
              svn_revnum_t revision,
              void *parent_baton,
              apr_pool_t *pool)
{
  struct dir_baton *db = parent_baton;
  struct edit_baton *eb = db->edit_baton;
  apr_hash_t *entries;
  const char *name = svn_path_basename (path, pool);
  const char *full_path = svn_path_join (eb->anchor, path, pool);
  const char *dir_path;
  svn_node_kind_t kind;
  svn_wc_adm_access_t *adm_access;
  const char *hash_key;

  /* Note:  when something is deleted, it's okay to tweak the
     statushash immediately.  No need to wait until close_file or
     close_dir, because there's no risk of having to honor the 'added'
     flag.  We already know this item exists in the working copy. */

  /* Read the parent's entries file.  If the deleted thing is not
     versioned in this working copy, it was probably deleted via this
     working copy.  No need to report such a thing. */
  /* ### use svn_wc_entry() instead? */
  SVN_ERR (svn_io_check_path (full_path, &kind, pool));
  if (kind == svn_node_dir)
    {
      dir_path = full_path;
      hash_key = SVN_WC_ENTRY_THIS_DIR;
    }
  else
    {
      dir_path = svn_path_dirname (full_path, pool);
      hash_key = name;
    }
  SVN_ERR (svn_wc_adm_retrieve (&adm_access, eb->adm_access, dir_path, pool));
  SVN_ERR (svn_wc_entries_read (&entries, adm_access, FALSE, pool));
  if (apr_hash_get (entries, hash_key, APR_HASH_KEY_STRING))
    SVN_ERR (tweak_statushash (db->statii, eb->adm_access,
                               full_path, kind == svn_node_dir,
                               svn_wc_status_deleted, 0));

  /* Mark the parent dir -- it lost an entry (unless that parent dir
     is the root node and we're not supposed to report on the root
     node).  */
  if (db->parent_baton && (! *eb->target))
    SVN_ERR (tweak_statushash (db->parent_baton->statii, eb->adm_access,
                               db->path, kind == svn_node_dir,
                               svn_wc_status_modified, 0));

  return SVN_NO_ERROR;
}


static svn_error_t *
add_directory (const char *path,
               void *parent_baton,
               const char *copyfrom_path,
               svn_revnum_t copyfrom_revision,
               apr_pool_t *pool,
               void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct dir_baton *new_db;

  SVN_ERR (make_dir_baton (child_baton, path, eb, pb, pool));

  /* Make this dir as added. */
  new_db = *child_baton;
  new_db->added = TRUE;

  /* Mark the parent as changed;  it gained an entry. */
  pb->text_changed = TRUE;

  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;
  return make_dir_baton (child_baton, path, pb->edit_baton, pb, pool);
}


static svn_error_t *
change_dir_prop (void *dir_baton,
                 const char *name,
                 const svn_string_t *value,
                 apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  if (svn_wc_is_normal_prop (name))    
    db->prop_changed = TRUE;
  return SVN_NO_ERROR;
}



static svn_error_t *
close_directory (void *dir_baton,
                 apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  struct dir_baton *pb = db->parent_baton;
  struct edit_baton *eb = db->edit_baton;
  svn_wc_status_t *dir_status = NULL;
  
  /* If nothing has changed, return. */
  if (db->added || db->prop_changed || db->text_changed)
    {
      enum svn_wc_status_kind repos_text_status;
      enum svn_wc_status_kind repos_prop_status;
  
      /* If this is a new file, add it to the statushash. */
      if (db->added)
        {
          repos_text_status = svn_wc_status_added;
          repos_prop_status = db->prop_changed ? svn_wc_status_added : 0;
        }
      else
        {
          repos_text_status = db->text_changed ? svn_wc_status_modified : 0;
          repos_prop_status = db->prop_changed ? svn_wc_status_modified : 0;
        }

      /* If this directory was added, add it to its parent's status hash. */
      if (pb)
        SVN_ERR (tweak_statushash (pb->statii,
                                   eb->adm_access,
                                   db->path, TRUE,
                                   repos_text_status,
                                   repos_prop_status));
    }

  /* Handle this directory's statuses, and then note in the parent
     that this has been done. */
  if (pb && eb->descend)
    {
      svn_boolean_t was_deleted = FALSE;

      /* See if the directory was deleted or replaced. */
      dir_status = apr_hash_get (pb->statii, db->path, APR_HASH_KEY_STRING);
      if (dir_status &&
          ((dir_status->repos_text_status == svn_wc_status_deleted)
           || (dir_status->repos_text_status == svn_wc_status_replaced)))
        was_deleted = TRUE;

      /* Now do the status reporting. */
      SVN_ERR (handle_statii (eb, dir_status ? dir_status->entry : NULL, 
                              db->path, db->statii, was_deleted, TRUE, pool));
      if (is_sendable_status (dir_status, eb))
        (eb->status_func) (eb->status_baton, db->path, dir_status);
      apr_hash_set (pb->statii, db->path, APR_HASH_KEY_STRING, NULL);
    }
  else if (! pb)
    {
      /* If this is the top-most directory, and the operation had a
         target, we should only report the target. */
      if (*eb->target)
        {
          svn_wc_status_t *tgt_status;
          const char *path = svn_path_join (eb->anchor, eb->target, pool);
          dir_status = eb->anchor_status;
          tgt_status = apr_hash_get (db->statii, path, APR_HASH_KEY_STRING);
          if (tgt_status)
            {
              if ((eb->descend)
                  && (tgt_status->entry)
                  && (tgt_status->entry->kind == svn_node_dir))
                {
                  svn_wc_adm_access_t *dir_access;
                  SVN_ERR (svn_wc_adm_retrieve (&dir_access, eb->adm_access, 
                                                path, pool));
                  SVN_ERR (get_dir_status 
                           (eb, tgt_status->entry, dir_access, NULL,
                            eb->ignores, TRUE, eb->get_all, eb->no_ignore, 
                            TRUE, eb->status_func, eb->status_baton, 
                            eb->cancel_func, eb->cancel_baton, pool));
                }
              if (is_sendable_status (tgt_status, eb))
                (eb->status_func) (eb->status_baton, path, tgt_status);
            }
        }
      else
        {
          /* Otherwise, we report on all our children and ourself.
             Note that our directory couldn't have been deleted,

⌨️ 快捷键说明

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