Esempio n. 1
0
svn_error_t *
svn_wc__adm_destroy(svn_wc__db_t *db,
                    const char *dir_abspath,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *scratch_pool)
{
  const char *adm_abspath;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));

  SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));

  SVN_ERR(svn_wc__db_get_wcroot(&adm_abspath, db, dir_abspath,
                                scratch_pool, scratch_pool));

  /* Well, the coast is clear for blowing away the administrative
     directory, which also removes remaining locks */

  /* Now close the DB, and we can delete the working copy */
  if (strcmp(adm_abspath, dir_abspath) == 0)
    {
      SVN_ERR(svn_wc__db_drop_root(db, adm_abspath, scratch_pool));
      SVN_ERR(svn_io_remove_dir2(svn_wc__adm_child(adm_abspath, NULL,
                                                   scratch_pool),
                                 FALSE,
                                 cancel_func, cancel_baton,
                                 scratch_pool));
    }

  return SVN_NO_ERROR;
}
Esempio n. 2
0
svn_error_t *
svn_wc__adm_cleanup_tmp_area(svn_wc__db_t *db,
                             const char *adm_abspath,
                             apr_pool_t *scratch_pool)
{
  const char *tmp_path;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(adm_abspath));

  SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));

  /* Get the path to the tmp area, and blow it away. */
  tmp_path = svn_wc__adm_child(adm_abspath, SVN_WC__ADM_TMP, scratch_pool);

  SVN_ERR(svn_io_remove_dir2(tmp_path, TRUE, NULL, NULL, scratch_pool));

  /* Now, rebuild the tmp area. */
  return svn_error_trace(init_adm_tmp_area(adm_abspath, scratch_pool));
}
Esempio n. 3
0
svn_error_t *
svn_wc_copy3(svn_wc_context_t *wc_ctx,
             const char *src_abspath,
             const char *dst_abspath,
             svn_boolean_t metadata_only,
             svn_cancel_func_t cancel_func,
             void *cancel_baton,
             svn_wc_notify_func2_t notify_func,
             void *notify_baton,
             apr_pool_t *scratch_pool)
{
  /* Verify that we have the required write lock. */
  SVN_ERR(svn_wc__write_check(wc_ctx->db,
                              svn_dirent_dirname(dst_abspath, scratch_pool),
                              scratch_pool));

  return svn_error_trace(copy_or_move(NULL, wc_ctx, src_abspath, dst_abspath,
                                      metadata_only, FALSE /* is_move */,
                                      TRUE /* allow_mixed_revisions */,
                                      cancel_func, cancel_baton,
                                      notify_func, notify_baton,
                                      scratch_pool));
}
Esempio n. 4
0
svn_error_t *
svn_wc__delete_many(svn_wc_context_t *wc_ctx,
                    const apr_array_header_t *targets,
                    svn_boolean_t keep_local,
                    svn_boolean_t delete_unversioned_target,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    svn_wc_notify_func2_t notify_func,
                    void *notify_baton,
                    apr_pool_t *scratch_pool)
{
  svn_wc__db_t *db = wc_ctx->db;
  svn_error_t *err;
  svn_wc__db_status_t status;
  svn_node_kind_t kind;
  svn_skel_t *work_items = NULL;
  apr_array_header_t *versioned_targets;
  const char *local_abspath;
  int i;
  apr_pool_t *iterpool;

  iterpool = svn_pool_create(scratch_pool);
  versioned_targets = apr_array_make(scratch_pool, targets->nelts,
                                     sizeof(const char *));
  for (i = 0; i < targets->nelts; i++)
    {
      svn_boolean_t conflicted = FALSE;
      const char *repos_relpath;

      svn_pool_clear(iterpool);

      local_abspath = APR_ARRAY_IDX(targets, i, const char *);
      err = svn_wc__db_read_info(&status, &kind, NULL, &repos_relpath, NULL,
                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                 NULL, &conflicted,
                                 NULL, NULL, NULL, NULL, NULL, NULL,
                                 db, local_abspath, iterpool, iterpool);

      if (err)
        {
          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
            {
              svn_error_clear(err);
              if (delete_unversioned_target && !keep_local)
                SVN_ERR(erase_unversioned_from_wc(local_abspath, FALSE,
                                                  cancel_func, cancel_baton,
                                                  iterpool));
              continue;
            }
         else
          return svn_error_trace(err);
        }

      APR_ARRAY_PUSH(versioned_targets, const char *) = local_abspath;

      switch (status)
        {
          /* svn_wc__db_status_server_excluded handled by
           * svn_wc__db_op_delete_many */
          case svn_wc__db_status_excluded:
          case svn_wc__db_status_not_present:
            return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                     _("'%s' cannot be deleted"),
                                     svn_dirent_local_style(local_abspath,
                                                            iterpool));

          /* Explicitly ignore other statii */
          default:
            break;
        }

      if (status == svn_wc__db_status_normal
          && kind == svn_node_dir)
        {
          svn_boolean_t is_wcroot;
          SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
                                       iterpool));

          if (is_wcroot)
            return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                                     _("'%s' is the root of a working copy and "
                                       "cannot be deleted"),
                                     svn_dirent_local_style(local_abspath,
                                                            iterpool));
        }
      if (repos_relpath && !repos_relpath[0])
        return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                                     _("'%s' represents the repository root "
                                       "and cannot be deleted"),
                                     svn_dirent_local_style(local_abspath,
                                                            iterpool));

      /* Verify if we have a write lock on the parent of this node as we might
         be changing the childlist of that directory. */
      SVN_ERR(svn_wc__write_check(db, svn_dirent_dirname(local_abspath,
                                                         iterpool),
                                  iterpool));

      /* Prepare the on-disk delete */
      if (!keep_local)
        {
          svn_skel_t *work_item;

          SVN_ERR(create_delete_wq_items(&work_item, db, local_abspath, kind,
                                         conflicted,
                                         scratch_pool, iterpool));

          work_items = svn_wc__wq_merge(work_items, work_item,
                                        scratch_pool);
        }
    }

  if (versioned_targets->nelts == 0)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__db_op_delete_many(db, versioned_targets,
                                    !keep_local /* delete_dir_externals */,
                                    work_items,
                                    cancel_func, cancel_baton,
                                    notify_func, notify_baton,
                                    iterpool));

  if (work_items != NULL)
    {
      /* Our only caller locked the wc, so for now assume it only passed
         nodes from a single wc (asserted in svn_wc__db_op_delete_many) */
      local_abspath = APR_ARRAY_IDX(versioned_targets, 0, const char *);

      SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
                             iterpool));
    }
Esempio n. 5
0
svn_error_t *
svn_wc__move2(svn_wc_context_t *wc_ctx,
              const char *src_abspath,
              const char *dst_abspath,
              svn_boolean_t metadata_only,
              svn_boolean_t allow_mixed_revisions,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
              svn_wc_notify_func2_t notify_func,
              void *notify_baton,
              apr_pool_t *scratch_pool)
{
  svn_wc__db_t *db = wc_ctx->db;
  svn_boolean_t move_degraded_to_copy = FALSE;
  svn_node_kind_t kind;
  svn_boolean_t conflicted;

  /* Verify that we have the required write locks. */
  SVN_ERR(svn_wc__write_check(wc_ctx->db,
                              svn_dirent_dirname(src_abspath, scratch_pool),
                              scratch_pool));
  SVN_ERR(svn_wc__write_check(wc_ctx->db,
                              svn_dirent_dirname(dst_abspath, scratch_pool),
                              scratch_pool));

  SVN_ERR(copy_or_move(&move_degraded_to_copy,
                       wc_ctx, src_abspath, dst_abspath,
                       TRUE /* metadata_only */,
                       TRUE /* is_move */,
                       allow_mixed_revisions,
                       cancel_func, cancel_baton,
                       notify_func, notify_baton,
                       scratch_pool));

  /* An interrupt at this point will leave the new copy marked as
     moved-here but the source has not yet been deleted or marked as
     moved-to. */

  /* Should we be using a workqueue for this move?  It's not clear.
     What should happen if the copy above is interrupted?  The user
     may want to abort the move and a workqueue might interfere with
     that.

     BH: On Windows it is not unlikely to encounter an access denied on
     this line. Installing the move in the workqueue via the copy_or_move
     might make it hard to recover from that situation, while the DB
     is still in a valid state. So be careful when switching this over
     to the workqueue. */
  if (!metadata_only)
    SVN_ERR(svn_io_file_rename(src_abspath, dst_abspath, scratch_pool));

  SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL,
                               &conflicted, NULL, NULL, NULL,
                               NULL, NULL, NULL,
                               db, src_abspath,
                               scratch_pool, scratch_pool));

  if (kind == svn_node_dir)
    SVN_ERR(remove_all_conflict_markers(db, src_abspath, dst_abspath,
                                        scratch_pool));

  if (conflicted)
    SVN_ERR(remove_node_conflict_markers(db, src_abspath, dst_abspath,
                                         scratch_pool));

  SVN_ERR(svn_wc__db_op_delete(db, src_abspath,
                               move_degraded_to_copy ? NULL : dst_abspath,
                               TRUE /* delete_dir_externals */,
                               NULL /* conflict */, NULL /* work_items */,
                               cancel_func, cancel_baton,
                               notify_func, notify_baton,
                               scratch_pool));

  return SVN_NO_ERROR;
}