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

📄 adm_ops.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (!strcmp (name, SVN_WC_ENTRY_THIS_DIR))
              continue;

            down_path = svn_path_join (path, name, pool);
            SVN_ERR (erase_from_wc (down_path, dir_access, entry->kind,
                                    cancel_func, cancel_baton, pool));
          }

        /* Now handle any remaining unversioned items */
        SVN_ERR (svn_io_get_dirents (&unver, path, pool));
        for (hi = apr_hash_first (pool, unver); hi; hi = apr_hash_next (hi))
          {
            const void *key;
            const char *name;
            const char *down_path;

            apr_hash_this (hi, &key, NULL, NULL);
            name = key;

            /* The admin directory will show up, we don't want to delete it */
            if (!strcmp (name, SVN_WC_ADM_DIR_NAME))
              continue;

            /* Versioned directories will show up, don't delete those either */
            if (apr_hash_get (ver, name, APR_HASH_KEY_STRING))
              continue;

            down_path = svn_path_join (path, name, pool);
            SVN_ERR (erase_unversioned_from_wc
                     (down_path, cancel_func, cancel_baton, pool));
          }
      }
      /* ### TODO: move this dir into parent's .svn area */
      break;
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_delete (const char *path,
               svn_wc_adm_access_t *adm_access,
               svn_cancel_func_t cancel_func,
               void *cancel_baton,
               svn_wc_notify_func_t notify_func,
               void *notify_baton,
               apr_pool_t *pool)
{
  svn_wc_adm_access_t *dir_access;
  const svn_wc_entry_t *entry;
  const char *parent, *base_name;
  svn_boolean_t was_schedule_add;
  svn_node_kind_t was_kind;
  svn_boolean_t was_deleted = FALSE; /* Silence a gcc uninitialized warning */

  SVN_ERR (svn_wc_adm_probe_try2 (&dir_access, adm_access, path,
                                  TRUE, -1, pool));
  if (dir_access)
    SVN_ERR (svn_wc_entry (&entry, path, dir_access, FALSE, pool));
  else
    entry = NULL;

  if (!entry)
    return erase_unversioned_from_wc (path, cancel_func, cancel_baton, pool);
    
  /* Note: Entries caching?  What happens to this entry when the entries
     file is updated?  Lets play safe and copy the values */
  was_schedule_add = entry->schedule == svn_wc_schedule_add;
  was_kind = entry->kind;

  svn_path_split (path, &parent, &base_name, pool);

  if (was_kind == svn_node_dir)
    {
      svn_wc_adm_access_t *parent_access;
      apr_hash_t *entries;
      const svn_wc_entry_t *entry_in_parent;

      /* The deleted state is only available in the entry in parent's
         entries file */
      SVN_ERR (svn_wc_adm_retrieve (&parent_access, adm_access, parent, pool));
      SVN_ERR (svn_wc_entries_read (&entries, parent_access, TRUE, pool));
      entry_in_parent = apr_hash_get (entries, base_name, APR_HASH_KEY_STRING);
      was_deleted = entry_in_parent ? entry_in_parent->deleted : FALSE;

      if (was_schedule_add && !was_deleted)
        {
          /* Deleting a directory that has been added but not yet
             committed is easy, just remove the administrative dir. */

          if (dir_access != adm_access)
            {
              SVN_ERR (svn_wc_remove_from_revision_control
                       (dir_access, SVN_WC_ENTRY_THIS_DIR, FALSE, FALSE,
                        cancel_func, cancel_baton, pool));
            }
          else
            {
              /* adm_probe_retrieve returned the parent access baton,
                 which is the same access baton that we came in here
                 with!  this means we're dealing with a missing item
                 that's scheduled for addition.  Easiest to just
                 remove the entry.  */
              svn_wc__entry_remove (entries, base_name);
              SVN_ERR (svn_wc__entries_write (entries, parent_access, pool));
            }
        }
      else
        {
          /* if adm_probe_retrieve returned the parent access baton,
             (which is the same access baton that we came in here
             with), this means we're dealing with a missing directory.
             So there's no tree to mark for deletion.  Instead, the
             next phase of code will simply schedule the directory for
             deletion in its parent. */
          if (dir_access != adm_access)
            {
              /* Recursively mark a whole tree for deletion. */
              SVN_ERR (mark_tree (dir_access, SVN_WC__ENTRY_MODIFY_SCHEDULE,
                                  svn_wc_schedule_delete, FALSE,
                                  cancel_func, cancel_baton,
                                  notify_func, notify_baton,
                                  pool));
            }
        }
    }
  
  if (!(was_kind == svn_node_dir && was_schedule_add && !was_deleted))
    {
      /* We need to mark this entry for deletion in its parent's entries
         file, so we split off base_name from the parent path, then fold in
         the addition of a delete flag. */
      svn_wc_entry_t tmp_entry;
      
      tmp_entry.schedule = svn_wc_schedule_delete;
      SVN_ERR (svn_wc__entry_modify (adm_access, base_name, &tmp_entry,
                                     SVN_WC__ENTRY_MODIFY_SCHEDULE, TRUE,
                                     pool));
    }

  /* Report the deletion to the caller. */
  if (notify_func != NULL)
    (*notify_func) (notify_baton, path, svn_wc_notify_delete,
                    svn_node_unknown,
                    NULL,
                    svn_wc_notify_state_unknown,
                    svn_wc_notify_state_unknown,
                    SVN_INVALID_REVNUM);

  /* By the time we get here, anything that was scheduled to be added has
     become unversioned */
  if (was_schedule_add)
    SVN_ERR (erase_unversioned_from_wc
             (path, cancel_func, cancel_baton, pool));
  else
    SVN_ERR (erase_from_wc (path, adm_access, was_kind,
                            cancel_func, cancel_baton, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_get_ancestry (char **url,
                     svn_revnum_t *rev,
                     const char *path,
                     svn_wc_adm_access_t *adm_access,
                     apr_pool_t *pool)
{
  const svn_wc_entry_t *ent;

  SVN_ERR (svn_wc_entry (&ent, path, adm_access, FALSE, pool));

  if (url)
    *url = apr_pstrdup (pool, ent->url);

  if (rev)
    *rev = ent->revision;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_add (const char *path,
            svn_wc_adm_access_t *parent_access,
            const char *copyfrom_url,
            svn_revnum_t copyfrom_rev,
            svn_cancel_func_t cancel_func,
            void *cancel_baton,
            svn_wc_notify_func_t notify_func,
            void *notify_baton,
            apr_pool_t *pool)
{
  const char *parent_dir, *base_name;
  const svn_wc_entry_t *orig_entry, *parent_entry;
  svn_wc_entry_t tmp_entry;
  svn_boolean_t is_replace = FALSE;
  svn_node_kind_t kind;
  apr_uint32_t modify_flags = 0;
  svn_wc_adm_access_t *adm_access;
  
  /* Make sure something's there. */
  SVN_ERR (svn_io_check_path (path, &kind, pool));
  if (kind == svn_node_none)
    return svn_error_createf (SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                              _("'%s' not found"), path);
  if (kind == svn_node_unknown)
    return svn_error_createf (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                              _("Unsupported node kind for path '%s'"), path);

  /* Get the original entry for this path if one exists (perhaps
     this is actually a replacement of a previously deleted thing).
     
     Note that this is one of the few functions that is allowed to see
    'deleted' entries;  it's totally fine to have an entry that is
     scheduled for addition and still previously 'deleted'.  */
  SVN_ERR (svn_wc_adm_probe_try2 (&adm_access, parent_access, path,
                                  TRUE, copyfrom_url != NULL ? -1 : 0,
                                  pool));
  if (adm_access)
    SVN_ERR (svn_wc_entry (&orig_entry, path, adm_access, TRUE, pool));
  else
    orig_entry = NULL;

  /* You can only add something that is not in revision control, or
     that is slated for deletion from revision control, or has been
     previously 'deleted', unless, of course, you're specifying an
     addition with -history-; then it's okay for the object to be
     under version control already; it's not really new.  */
  if (orig_entry)
    {
      if ((! copyfrom_url) 
          && (orig_entry->schedule != svn_wc_schedule_delete)
          && (! orig_entry->deleted))
        {
          return svn_error_createf 
            (SVN_ERR_ENTRY_EXISTS, NULL,
             _("'%s' is already under version control"), path);
        }
      else if (orig_entry->kind != kind)
        {
          /* ### todo: At some point, we obviously don't want to block
             replacements where the node kind changes.  When this
             happens, svn_wc_revert() needs to learn how to revert
             this situation.  At present we are using a specific node-change
             error so that clients can detect it. */
          return svn_error_createf 
            (SVN_ERR_WC_NODE_KIND_CHANGE, NULL,
             _("Can't replace '%s' with a node of a differing type; "
               "commit the deletion, update the parent, and then add '%s'"),
             path, path);
        }
      if (orig_entry->schedule == svn_wc_schedule_delete)
        is_replace = TRUE;
    }

  /* Split off the base_name from the parent directory. */
  svn_path_split (path, &parent_dir, &base_name, pool);
  SVN_ERR (svn_wc_entry (&parent_entry, parent_dir, parent_access, FALSE,
                         pool));
  if (! parent_entry)
    return svn_error_createf 
      (SVN_ERR_ENTRY_NOT_FOUND, NULL,
       _("Can't find parent directory's entry while trying to add '%s'"),
       path);
  if (parent_entry->schedule == svn_wc_schedule_delete)
    return svn_error_createf 
      (SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
       _("Can't add '%s' to a parent directory scheduled for deletion"),
       path);

  /* Init the modify flags. */
  modify_flags = SVN_WC__ENTRY_MODIFY_SCHEDULE | SVN_WC__ENTRY_MODIFY_KIND;
  if (! (is_replace || copyfrom_url))
    modify_flags |= SVN_WC__ENTRY_MODIFY_REVISION;

  /* If a copy ancestor was given, put the proper ancestry info in a hash. */
  if (copyfrom_url)
    {
      tmp_entry.copyfrom_url = copyfrom_url;
      tmp_entry.copyfrom_rev = copyfrom_rev;
      tmp_entry.copied = TRUE;
      modify_flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL;
      modify_flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_REV;
      modify_flags |= SVN_WC__ENTRY_MODIFY_COPIED;
    }

  tmp_entry.revision = 0;
  tmp_entry.kind = kind;
  tmp_entry.schedule = svn_wc_schedule_add;

  /* Now, add the entry for this item to the parent_dir's
     entries file, marking it for addition. */
  SVN_ERR (svn_wc__entry_modify (parent_access, base_name, &tmp_entry, 
                                 modify_flags, TRUE, pool));


  /* If this is a replacement without history, we need to reset the
     properties for PATH. */
  if (orig_entry && (! copyfrom_url))
    {
      const char *prop_path;
      SVN_ERR (svn_wc__prop_path (&prop_path, path, adm_access, FALSE, pool));
      SVN_ERR (remove_file_if_present (prop_path, pool));
    }

  if (kind == svn_node_dir) /* scheduling a directory for addition */
    {
      if (! copyfrom_url)
        {
          const svn_wc_entry_t *p_entry; /* ### why not use parent_entry? */
          const char *new_url;

          /* Get the entry for this directory's parent.  We need to snatch
             the ancestor path out of there. */
          SVN_ERR (svn_wc_entry (&p_entry, parent_dir, parent_access, FALSE,
                                 pool));
  
          /* Derive the parent path for our new addition here. */
          new_url = svn_path_url_add_component (p_entry->url, base_name, pool);
  
          /* Make sure this new directory has an admistrative subdirectory
             created inside of it */
          SVN_ERR (svn_wc_ensure_adm (path, NULL, new_url, 0, pool));
        }
      else
        {
          /* When we are called with the copyfrom arguments set and with
             the admin directory already in existance, then the dir will
             contain the copyfrom settings.  So we need to pass the
             copyfrom arguments to the ensure call. */
          SVN_ERR (svn_wc_ensure_adm (path, NULL, copyfrom_url, 
                                      copyfrom_rev, pool));
        }
      
      /* We want the locks to persist, so use the access baton's pool */
      if (! orig_entry || orig_entry->deleted)

⌨️ 快捷键说明

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