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

📄 entries.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 5 页
字号:
        }
      break;

    case svn_wc_schedule_delete:
      switch (*schedule)
        {
        case svn_wc_schedule_normal:
        case svn_wc_schedule_delete:
          /* These are no-op cases. */
          *modify_flags &= ~SVN_WC__ENTRY_MODIFY_SCHEDULE;
          return SVN_NO_ERROR;


        case svn_wc_schedule_add:
          /* Re-adding an entry marked for deletion?  This is really a
             replace operation. */
          *schedule = svn_wc_schedule_replace;
          return SVN_NO_ERROR;


        case svn_wc_schedule_replace:
          /* Replacing an item marked for deletion breaks down to
             (delete + (delete + add)), which might deserve a warning,
             but whatever. */
          return SVN_NO_ERROR;

        }
      break;

    case svn_wc_schedule_replace:
      switch (*schedule)
        {
        case svn_wc_schedule_normal:
          /* These are all no-op cases. */
        case svn_wc_schedule_add:
          /* Adding a to-be-replaced entry breaks down to ((delete +
             add) + add) which might deserve a warning, but we'll just
             no-op it. */
        case svn_wc_schedule_replace:
          /* Replacing a to-be-replaced entry breaks down to ((delete
             + add) + (delete + add)), which is insane!  Make up your
             friggin' mind, dude! :-)  Well, we'll no-op this one,
             too. */
          *modify_flags &= ~SVN_WC__ENTRY_MODIFY_SCHEDULE;
          return SVN_NO_ERROR;
          

        case svn_wc_schedule_delete:
          /* Deleting a to-be-replaced entry breaks down to ((delete +
             add) + delete) which resolves to a flat deletion. */
          *schedule = svn_wc_schedule_delete;
          return SVN_NO_ERROR;

        }
      break;

    default:
      return 
        svn_error_createf 
        (SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
         _("Entry '%s' has illegal schedule"), name);
    }
  return SVN_NO_ERROR;
}



svn_error_t *
svn_wc__entry_modify (svn_wc_adm_access_t *adm_access,
                      const char *name,
                      svn_wc_entry_t *entry,
                      apr_uint32_t modify_flags,
                      svn_boolean_t do_sync,
                      apr_pool_t *pool)
{
  apr_hash_t *entries, *entries_nohidden;
  svn_boolean_t entry_was_deleted_p = FALSE;

  /* ENTRY is rather necessary, and ENTRY->kind is required to be valid! */
  assert (entry);

  /* Load PATH's whole entries file. */
  SVN_ERR (svn_wc_entries_read (&entries, adm_access, TRUE, pool));
  SVN_ERR (svn_wc_entries_read (&entries_nohidden, adm_access, FALSE, pool));

  /* Ensure that NAME is valid. */
  if (name == NULL)
    name = SVN_WC_ENTRY_THIS_DIR;

  if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE)
    {
      svn_wc_entry_t *entry_before, *entry_after;
      apr_uint32_t orig_modify_flags = modify_flags;
      svn_wc_schedule_t orig_schedule = entry->schedule;

      /* Keep a copy of the unmodified entry on hand. */
      entry_before = apr_hash_get (entries, name, APR_HASH_KEY_STRING);
      
      /* If scheduling changes were made, we have a special routine to
         manage those modifications. */
      SVN_ERR (fold_scheduling (entries, name, &modify_flags, 
                                &entry->schedule, pool));
      
      if (entries != entries_nohidden)
        {
          SVN_ERR (fold_scheduling (entries_nohidden, name, &orig_modify_flags,
                                    &orig_schedule, pool));
          
          /* Make certain that both folding operations had the same
             result. */
          assert(orig_modify_flags == modify_flags);
          assert(orig_schedule == entry->schedule);
        }

      /* Special case:  fold_state_changes() may have actually REMOVED
         the entry in question!  If so, don't try to fold_entry, as
         this will just recreate the entry again. */
      entry_after = apr_hash_get (entries, name, APR_HASH_KEY_STRING);

      /* Note if this entry was deleted above so we don't accidentally
         re-add it in the following steps. */
      if (entry_before && (! entry_after))
        entry_was_deleted_p = TRUE;
    }

  /* If the entry wasn't just removed from the entries hash, fold the
     changes into the entry. */
  if (! entry_was_deleted_p)
    {
      fold_entry (entries, name, modify_flags, entry,
                  svn_wc_adm_access_pool (adm_access));
      if (entries != entries_nohidden)
        fold_entry (entries_nohidden, name, modify_flags, entry,
                    svn_wc_adm_access_pool (adm_access));
    }

  /* Sync changes to disk. */
  if (do_sync)
    SVN_ERR (svn_wc__entries_write (entries, adm_access, pool));

  return SVN_NO_ERROR;
}


svn_wc_entry_t *
svn_wc_entry_dup (const svn_wc_entry_t *entry, apr_pool_t *pool)
{
  svn_wc_entry_t *dupentry = apr_pcalloc (pool, sizeof(*dupentry));

  /* Perform a trivial copy ... */
  *dupentry = *entry;

  /* ...and then re-copy stuff that needs to be duped into our pool. */
  if (entry->name)
    dupentry->name = apr_pstrdup (pool, entry->name);
  if (entry->url)
    dupentry->url = apr_pstrdup (pool, entry->url);
  if (entry->repos)
    dupentry->repos = apr_pstrdup (pool, entry->repos);
  if (entry->uuid)
    dupentry->uuid = apr_pstrdup (pool, entry->uuid);
  if (entry->copyfrom_url)
    dupentry->copyfrom_url = apr_pstrdup (pool, entry->copyfrom_url);
  if (entry->conflict_old)
    dupentry->conflict_old = apr_pstrdup (pool, entry->conflict_old);
  if (entry->conflict_new)
    dupentry->conflict_new = apr_pstrdup (pool, entry->conflict_new);
  if (entry->conflict_wrk)
    dupentry->conflict_wrk = apr_pstrdup (pool, entry->conflict_wrk);
  if (entry->prejfile)
    dupentry->prejfile = apr_pstrdup (pool, entry->prejfile);
  if (entry->checksum)
    dupentry->checksum = apr_pstrdup (pool, entry->checksum);
  if (entry->cmt_author)
    dupentry->cmt_author = apr_pstrdup (pool, entry->cmt_author);

  return dupentry;
}


svn_error_t *
svn_wc__tweak_entry (apr_hash_t *entries,
                     const char *name,
                     const char *new_url,
                     svn_revnum_t new_rev,
                     svn_boolean_t *write_required,
                     apr_pool_t *pool)
{
  svn_wc_entry_t *entry;

  entry = apr_hash_get (entries, name, APR_HASH_KEY_STRING);
  if (! entry)
    return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, NULL,
                              _("No such entry: '%s'"), name);

  if (new_url != NULL
      && (! entry->url || strcmp (new_url, entry->url)))
    {
      *write_required = TRUE;
      entry->url = apr_pstrdup (pool, new_url);
    }

  if ((SVN_IS_VALID_REVNUM (new_rev))
      && (entry->schedule != svn_wc_schedule_add)
      && (entry->schedule != svn_wc_schedule_replace)
      && (entry->revision != new_rev))
    {
      *write_required = TRUE;
      entry->revision = new_rev;
    }

  /* As long as this function is only called as a helper to
     svn_wc__do_update_cleanup, then it's okay to remove any entry
     under certain circumstances:

     If the entry is still marked 'deleted', then the server did not
     re-add it.  So it's really gone in this revision, thus we remove
     the entry.

     If the entry is still marked 'absent' and yet is not the same
     revision as new_rev, then the server did not re-add it, nor
     re-absent it, so we can remove the entry. */
  if ((entry->deleted)
      || (entry->absent && (entry->revision != new_rev)))
    {
      *write_required = TRUE;
      apr_hash_set (entries, name, APR_HASH_KEY_STRING, NULL);
    }

  return SVN_NO_ERROR;
}




/*** Generic Entry Walker */


/* A recursive entry-walker, helper for svn_wc_walk_entries */
static svn_error_t *
walker_helper (const char *dirpath,
               svn_wc_adm_access_t *adm_access,
               const svn_wc_entry_callbacks_t *walk_callbacks,
               void *walk_baton,
               svn_boolean_t show_hidden,
               apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create (pool);
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  svn_wc_entry_t *dot_entry;

  SVN_ERR (svn_wc_entries_read (&entries, adm_access, show_hidden, pool));
  
  /* As promised, always return the '.' entry first. */
  dot_entry = apr_hash_get (entries, SVN_WC_ENTRY_THIS_DIR, 
                            APR_HASH_KEY_STRING);
  if (! dot_entry)
    return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, NULL,
                              _("Directory '%s' has no THIS_DIR entry"),
                              dirpath);

  SVN_ERR (walk_callbacks->found_entry (dirpath, dot_entry, walk_baton, pool));

  /* Loop over each of the other entries. */
  for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t klen;
      void *val;
      const svn_wc_entry_t *current_entry; 
      const char *entrypath;

      apr_hash_this (hi, &key, &klen, &val);
      current_entry = val;

      if (strcmp (current_entry->name, SVN_WC_ENTRY_THIS_DIR) == 0)
        continue;

      entrypath = svn_path_join (dirpath, key, subpool);
      SVN_ERR (walk_callbacks->found_entry (entrypath, current_entry,
                                            walk_baton, subpool));

      if (current_entry->kind == svn_node_dir)
        {
          svn_wc_adm_access_t *entry_access;
          SVN_ERR (svn_wc_adm_retrieve (&entry_access, adm_access, entrypath,
                                        subpool));
          SVN_ERR (walker_helper (entrypath, entry_access,
                                  walk_callbacks, walk_baton,
                                  show_hidden, subpool));
        }

      svn_pool_clear (subpool);
    }

  svn_pool_destroy (subpool);
  return SVN_NO_ERROR;
}


/* The public function */
svn_error_t *
svn_wc_walk_entries (const char *path,
                     svn_wc_adm_access_t *adm_access,
                     const svn_wc_entry_callbacks_t *walk_callbacks,
                     void *walk_baton,
                     svn_boolean_t show_hidden,
                     apr_pool_t *pool)
{
  const svn_wc_entry_t *entry;
  
  SVN_ERR (svn_wc_entry (&entry, path, adm_access, show_hidden, pool));

  if (! entry)
    return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                              _("'%s' is not under version control"), path);

  if (entry->kind == svn_node_file)
    return walk_callbacks->found_entry (path, entry, walk_baton, pool);

  else if (entry->kind == svn_node_dir)
    return walker_helper (path, adm_access, walk_callbacks, walk_baton,
                          show_hidden, pool);

  else
    return svn_error_createf (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
                              _("'%s' has an unrecognized node kind"), path);
}


svn_error_t *
svn_wc_mark_missing_deleted (const char *path,
                             svn_wc_adm_access_t *parent,
                             apr_pool_t *pool)
{
  svn_node_kind_t pkind;

  SVN_ERR (svn_io_check_path (path, &pkind, pool));

  if (pkind == svn_node_none)
    {
      const char *parent_path, *bname;
      svn_wc_adm_access_t *adm_access;
      svn_wc_entry_t newent;
      
      newent.deleted = TRUE;
      newent.schedule = svn_wc_schedule_normal;

      svn_path_split (path, &parent_path, &bname, pool);

      SVN_ERR (svn_wc_adm_retrieve (&adm_access, parent, parent_path, pool));
      SVN_ERR (svn_wc__entry_modify (adm_access, bname, &newent,
                                     (SVN_WC__ENTRY_MODIFY_DELETED
                                      | SVN_WC__ENTRY_MODIFY_SCHEDULE
                                      | SVN_WC__ENTRY_MODIFY_FORCE),
                                     TRUE, /* sync right away */ pool));

      return SVN_NO_ERROR;
    }
  else
    return svn_error_createf (SVN_ERR_WC_PATH_FOUND, NULL,
                              _("Unexpectedly found '%s': "
                                "path is marked 'missing'"), path);
}

⌨️ 快捷键说明

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