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

📄 copy.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
      apr_array_header_t *commit_items         = apr_array_make(pool, 2, sizeof(item));            item = apr_pcalloc(pool, sizeof(*item));      item->url = svn_path_join(top_url, dst_rel, pool);      item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;      APR_ARRAY_PUSH(commit_items, svn_client_commit_item2_t *) = item;      if (is_move && (! resurrection))        {          item = apr_pcalloc(pool, sizeof(*item));          item->url = svn_path_join(top_url, src_rel, pool);          item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;          APR_ARRAY_PUSH(commit_items, svn_client_commit_item2_t *) = item;        }      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,                                      ctx, pool));      if (! message)        return SVN_NO_ERROR;    }  else    message = "";  /* Fetch RA commit editor. */  SVN_ERR(svn_client__commit_get_baton(&commit_baton, commit_info_p, pool));  SVN_ERR(svn_ra_get_commit_editor2(ra_session, &editor, &edit_baton,                                    message,                                    svn_client__commit_callback,                                    commit_baton,                                     NULL, TRUE, /* No lock tokens */                                    pool));  /* Setup our PATHS for the path-based editor drive. */  APR_ARRAY_PUSH(paths, const char *) = dst_rel;  if (is_move && (! resurrection))    APR_ARRAY_PUSH(paths, const char *) = src_rel;  /* Setup the callback baton. */  cb_baton.editor = editor;  cb_baton.edit_baton = edit_baton;  cb_baton.src_kind = src_kind;  cb_baton.src_url = src_url;  cb_baton.src_path = src_rel;  cb_baton.dst_path = dst_rel;  cb_baton.is_move = is_move;  cb_baton.src_revnum = src_revnum;  cb_baton.resurrection = resurrection;  /* Call the path-based editor driver. */  err = svn_delta_path_driver(editor, edit_baton, youngest, paths,                              path_driver_cb_func, &cb_baton, pool);  if (err)    {      /* At least try to abort the edit (and fs txn) before throwing err. */      svn_error_clear(editor->abort_edit(edit_baton, pool));      return err;    }  /* Close the edit. */  SVN_ERR(editor->close_edit(edit_baton, pool));  return SVN_NO_ERROR;}static svn_error_t *remove_tmpfiles(apr_hash_t *tempfiles,                svn_cancel_func_t cancel_func,                void *cancel_baton,                apr_pool_t *pool){  apr_hash_index_t *hi;  /* Split if there's nothing to be done. */  if (! tempfiles)    return SVN_NO_ERROR;  /* Clean up any tempfiles. */  for (hi = apr_hash_first(pool, tempfiles); hi; hi = apr_hash_next(hi))    {      const void *key;      apr_ssize_t keylen;      void *val;      svn_node_kind_t kind;      if (cancel_func)        SVN_ERR(cancel_func(cancel_baton));      apr_hash_this(hi, &key, &keylen, &val);      SVN_ERR(svn_io_check_path((const char *)key, &kind, pool));      if (kind == svn_node_file)        SVN_ERR(svn_io_remove_file((const char *)key, pool));    }  return SVN_NO_ERROR;}static svn_error_t *reconcile_errors(svn_error_t *commit_err,                 svn_error_t *unlock_err,                 svn_error_t *cleanup_err,                 apr_pool_t *pool){  svn_error_t *err;  /* Early release (for good behavior). */  if (! (commit_err || unlock_err || cleanup_err))    return SVN_NO_ERROR;  /* If there was a commit error, start off our error chain with     that. */  if (commit_err)    {      commit_err = svn_error_quick_wrap         (commit_err, _("Commit failed (details follow):"));      err = commit_err;    }  /* Else, create a new "general" error that will lead off the errors     that follow. */  else    err = svn_error_create(SVN_ERR_BASE, NULL,                           _("Commit succeeded, but other errors follow:"));  /* If there was an unlock error... */  if (unlock_err)    {      /* Wrap the error with some headers. */      unlock_err = svn_error_quick_wrap         (unlock_err, _("Error unlocking locked dirs (details follow):"));      /* Append this error to the chain. */      svn_error_compose(err, unlock_err);    }  /* If there was a cleanup error... */  if (cleanup_err)    {      /* Wrap the error with some headers. */      cleanup_err = svn_error_quick_wrap         (cleanup_err, _("Error in post-commit clean-up (details follow):"));      /* Append this error to the chain. */      svn_error_compose(err, cleanup_err);    }  return err;}static svn_error_t *wc_to_repos_copy(svn_commit_info_t **commit_info_p,                 const char *src_path,                  const char *dst_url,                  svn_client_ctx_t *ctx,                 apr_pool_t *pool){  const char *anchor, *target, *message;  svn_ra_session_t *ra_session;  const svn_delta_editor_t *editor;  void *edit_baton;  svn_node_kind_t src_kind, dst_kind;  void *commit_baton;  apr_hash_t *committables, *tempfiles = NULL;  svn_wc_adm_access_t *adm_access, *dir_access;  apr_array_header_t *commit_items;  svn_error_t *cmt_err = SVN_NO_ERROR;  svn_error_t *unlock_err = SVN_NO_ERROR;  svn_error_t *cleanup_err = SVN_NO_ERROR;  const char *base_path;  /* The commit process uses absolute paths, so we need to open the access     baton using absolute paths, and so we really need to use absolute     paths everywhere. */  SVN_ERR(svn_path_get_absolute(&base_path, src_path, pool));  SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, base_path,                                 FALSE, -1, ctx->cancel_func,                                 ctx->cancel_baton, pool));  /* Split the DST_URL into an anchor and target. */  svn_path_split(dst_url, &anchor, &target, pool);  /* Open an RA session for the anchor URL. */  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, anchor,                                               svn_wc_adm_access_path                                               (adm_access),                                               adm_access, NULL, TRUE, TRUE,                                                ctx, pool));  /* Figure out the basename that will result from this operation. */  SVN_ERR(svn_ra_check_path(ra_session, svn_path_uri_decode(target, pool),                            SVN_INVALID_REVNUM, &dst_kind, pool));    if (dst_kind != svn_node_none)    {      return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,                               _("Path '%s' already exists"), dst_url);    }  /* Create a new commit item and add it to the array. */  if (ctx->log_msg_func || ctx->log_msg_func2)    {      svn_client_commit_item2_t *item;      const char *tmp_file;      commit_items = apr_array_make(pool, 1, sizeof(item));            item = apr_pcalloc(pool, sizeof(*item));      item->url = dst_url;      item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;      APR_ARRAY_PUSH(commit_items, svn_client_commit_item2_t *) = item;      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,                                      ctx, pool));      if (! message)        return SVN_NO_ERROR;    }  else    message = "";  /* Crawl the working copy for commit items. */  SVN_ERR(svn_io_check_path(base_path, &src_kind, pool));  if (src_kind == svn_node_dir)    SVN_ERR(svn_wc_adm_retrieve(&dir_access, adm_access, base_path, pool));  else    dir_access = adm_access;  if ((cmt_err = svn_client__get_copy_committables(&committables,                                                    dst_url,                                                   base_path,                                                   dir_access,                                                   ctx,                                                   pool)))    goto cleanup;  /* ### todo: There should be only one hash entry, which currently     has a hacked name until we have the entries files storing     canonical repository URLs.  Then, the hacked name can go away and     be replaced with a entry->repos (or whereever the entry's     canonical repos URL is stored). */  if (! ((commit_items = apr_hash_get(committables,                                       SVN_CLIENT__SINGLE_REPOS_NAME,                                       APR_HASH_KEY_STRING))))    goto cleanup;  /* Sort and condense our COMMIT_ITEMS. */  if ((cmt_err = svn_client__condense_commit_items(&dst_url,                                                    commit_items,                                                    pool)))    goto cleanup;  /* Open an RA session to DST_URL. */  if ((cmt_err = svn_client__open_ra_session_internal(&ra_session, dst_url,                                                      NULL, NULL,                                                      commit_items,                                                      FALSE, FALSE,                                                      ctx, pool)))    goto cleanup;  /* Fetch RA commit editor. */  SVN_ERR(svn_client__commit_get_baton(&commit_baton, commit_info_p, pool));  if ((cmt_err = svn_ra_get_commit_editor2(ra_session, &editor, &edit_baton,                                            message,                                           svn_client__commit_callback,                                           commit_baton,                                            NULL, TRUE, /* No lock tokens */                                           pool)))    goto cleanup;  /* Perform the commit. */  cmt_err = svn_client__do_commit(dst_url, commit_items, adm_access,                                  editor, edit_baton,                                   0, /* ### any notify_path_offset needed? */                                  &tempfiles, NULL, ctx, pool);  /* Sleep to ensure timestamp integrity. */  svn_sleep_for_timestamps(); cleanup:  /* It's only a read lock, so unlocking is harmless. */  unlock_err = svn_wc_adm_close(adm_access);  /* Remove any outstanding temporary text-base files. */  if (tempfiles)    cleanup_err = remove_tmpfiles(tempfiles,                                  ctx->cancel_func, ctx->cancel_baton,                                  pool);  return reconcile_errors(cmt_err, unlock_err, cleanup_err, pool);}static svn_error_t *repos_to_wc_copy(const char *src_url,                 const svn_opt_revision_t *src_revision,                 const char *dst_path,                  svn_client_ctx_t *ctx,                 apr_pool_t *pool){  svn_ra_session_t *ra_session;  svn_node_kind_t src_kind, dst_kind, dst_parent_kind;  svn_revnum_t src_revnum;  svn_wc_adm_access_t *adm_access;  const char *dst_parent;  const char *src_uuid = NULL, *dst_uuid = NULL;  svn_boolean_t same_repositories;  svn_opt_revision_t revision;  /* Open a repository session to the given URL. We do not (yet) have a     working copy, so we don't have a corresponding path and tempfiles     cannot go into the admin area. */  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, src_url, NULL,                                               NULL, NULL, FALSE, TRUE,                                                ctx, pool));    /* Pass null for the path, to ensure error if trying to get a     revision based on the working copy.  And additionally, we can't     pass an 'unspecified' revnum to the update reporter;  assume HEAD     if not specified. */  revision.kind = src_revision->kind;  revision.value = src_revision->value;  if (revision.kind == svn_opt_revision_unspecified)    revision.kind = svn_opt_revision_head;  SVN_ERR(svn_client__get_revision_number          (&src_revnum, ra_session, &revision, NULL, pool));  /* Verify that SRC_URL exists in the repository. */  SVN_ERR(svn_ra_check_path(ra_session, "", src_revnum, &src_kind, pool));  if (src_kind == svn_node_none)    {      if (SVN_IS_VALID_REVNUM(src_revnum))        return svn_error_createf          (SVN_ERR_FS_NOT_FOUND, NULL,           _("Path '%s' not found in revision %ld"),           src_url, src_revnum);      else        return svn_error_createf          (SVN_ERR_FS_NOT_FOUND, NULL,           _("Path '%s' not found in head revision"), src_url);    }  /* First, figure out about dst. */  SVN_ERR(svn_io_check_path(dst_path, &dst_kind, pool));  if (dst_kind != svn_node_none)    {      return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,                               _("Path '%s' already exists"),                               svn_path_local_style(dst_path, pool));    }  /* Make sure the destination parent is a directory and produce a clear     error message if it is not. */  dst_parent = svn_path_dirname(dst_path, pool);  SVN_ERR(svn_io_check_path(svn_path_dirname(dst_path, pool),                            &dst_parent_kind, pool));  if (dst_parent_kind != svn_node_dir)    return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, NULL,                             _("Path '%s' is not a directory"),                             svn_path_local_style(dst_parent, pool));  SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, dst_path, TRUE,                                 0, ctx->cancel_func, ctx->cancel_baton,                                 pool));  /* We've already checked for physical obstruction by a working file.     But there could also be logical obstruction by an entry whose     working file happens to be missing.*/   {    const svn_wc_entry_t *ent;    SVN_ERR(svn_wc_entry(&ent, dst_path, adm_access, FALSE, pool));    if (ent && (ent->kind != svn_node_dir) &&         (ent->schedule != svn_wc_schedule_delete))      return svn_error_createf        (SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,         _("Entry for '%s' exists (though the working file is missing)"),         svn_path_local_style(dst_path, pool));  }  /* Decide whether the two repositories are the same or not. */  {     svn_error_t *src_err, *dst_err;    const char *parent;       /* Get the repository uuid of SRC_URL */    src_err = svn_ra_get_uuid(ra_session, &src_uuid, pool);    if (src_err && src_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)      return src_err;    /* Get repository uuid of dst's parent directory, since dst may       not exist.  ### TODO:  we should probably walk up the wc here,       in case the parent dir has an imaginary URL.  */    svn_path_split(dst_path, &parent, NULL, pool);    dst_err = svn_client_uuid_from_path(&dst_uuid, parent, adm_access,                                        ctx, pool);    if (dst_err && dst_err->apr_err != SVN_ERR_RA_NO_REPOS_UUID)      return dst_err;        /* If either of the UUIDs are nonexistent, then at least one of       the repositories must be very old.  Rather than punish the       user, just assume the repositories are different, so no

⌨️ 快捷键说明

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