You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/12/14 02:25:00 UTC
svn commit: r1421631 - in /subversion/branches/ev2-export: ./
subversion/libsvn_client/commit.c subversion/libsvn_client/import.c
Author: hwright
Date: Fri Dec 14 01:24:55 2012
New Revision: 1421631
URL: http://svn.apache.org/viewvc?rev=1421631&view=rev
Log:
On the ev2-export branch:
Bring up-to-date with trunk@1421408, splitting the Ev2 import implementation
to follow the change on trunk.
Added:
subversion/branches/ev2-export/subversion/libsvn_client/import.c
- copied, changed from r1421408, subversion/trunk/subversion/libsvn_client/import.c
Modified:
subversion/branches/ev2-export/ (props changed)
subversion/branches/ev2-export/subversion/libsvn_client/commit.c
Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1421408
Modified: subversion/branches/ev2-export/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/commit.c?rev=1421631&r1=1421630&r2=1421631&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/commit.c Fri Dec 14 01:24:55 2012
@@ -30,11 +30,8 @@
#include <string.h>
#include <apr_strings.h>
#include <apr_hash.h>
-#include <apr_md5.h>
#include "svn_wc.h"
#include "svn_ra.h"
-#include "svn_delta.h"
-#include "svn_subst.h"
#include "svn_client.h"
#include "svn_string.h"
#include "svn_pools.h"
@@ -42,612 +39,15 @@
#include "svn_error_codes.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
-#include "svn_io.h"
-#include "svn_time.h"
#include "svn_sorts.h"
-#include "svn_props.h"
#include "svn_hash.h"
#include "client.h"
#include "private/svn_wc_private.h"
-#include "private/svn_subr_private.h"
#include "private/svn_ra_private.h"
-#include "private/svn_magic.h"
#include "svn_private_config.h"
-/* Import context baton.
-
- ### TODO: Add the following items to this baton:
- /` import editor/baton. `/
- const svn_delta_editor_t *editor;
- void *edit_baton;
-
- /` Client context baton `/
- svn_client_ctx_t `ctx;
-
- /` Paths (keys) excluded from the import (values ignored) `/
- apr_hash_t *excludes;
-*/
-typedef struct import_ctx_t
-{
- /* Whether any changes were made to the repository */
- svn_boolean_t repos_changed;
-
- /* A magic cookie for mime-type detection. */
- svn_magic__cookie_t *magic_cookie;
-
- /* Collection of all possible configuration file dictated auto-props and
- svn:auto-props. A hash mapping const char * file patterns to a
- second hash which maps const char * property names to const char *
- property values. Properties which don't have a value, e.g.
- svn:executable, simply map the property name to an empty string.
- May be NULL if autoprops are disabled. */
- apr_hash_t *autoprops;
-} import_ctx_t;
-
-
-/* Import file PATH as EDIT_PATH in the repository directory indicated
- * by DIR_BATON in EDITOR.
- *
- * Accumulate file paths and their batons in FILES, which must be
- * non-null. (These are used to send postfix textdeltas later).
- *
- * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON
- * for each file.
- *
- * Use POOL for any temporary allocation.
- */
-static svn_error_t *
-import_file(svn_editor_t *editor,
- const char *local_abspath,
- const char *relpath,
- const svn_io_dirent2_t *dirent,
- import_ctx_t *import_ctx,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
-{
- const char *mimetype = NULL;
- svn_stream_t *contents;
- svn_checksum_t *checksum;
- apr_hash_t* properties = NULL;
-
- SVN_ERR(svn_path_check_valid(local_abspath, pool));
-
- /* Remember that the repository was modified */
- import_ctx->repos_changed = TRUE;
-
- if (! dirent->special)
- {
- /* add automatic properties */
- SVN_ERR(svn_client__get_paths_auto_props(&properties, &mimetype,
- local_abspath,
- import_ctx->magic_cookie,
- import_ctx->autoprops,
- ctx, pool, pool));
- }
-
- if (!properties)
- properties = apr_hash_make(pool);
-
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify
- = svn_wc_create_notify(local_abspath, svn_wc_notify_commit_added,
- pool);
- notify->kind = svn_node_file;
- notify->mime_type = mimetype;
- notify->content_state = notify->prop_state
- = svn_wc_notify_state_inapplicable;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
- }
-
- /* If this is a special file, we need to set the svn:special
- property and create a temporary detranslated version in order to
- send to the server. */
- if (dirent->special)
- apr_hash_set(properties, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING,
- svn_string_create(SVN_PROP_BOOLEAN_TRUE, pool));
-
- /* Now, transmit the file contents. */
- SVN_ERR(svn_client__get_detranslated_stream(&contents, &checksum, NULL,
- local_abspath, properties, TRUE,
- pool, pool));
-
- SVN_ERR(svn_editor_add_file(editor, relpath, checksum, contents, properties,
- SVN_INVALID_REVNUM));
-
- return SVN_NO_ERROR;
-}
-
-
-/* Return in CHILDREN a mapping of basenames to dirents for the importable
- * children of DIR_ABSPATH. EXCLUDES is a hash of absolute paths to filter
- * out. IGNORES and GLOBAL_IGNORES, if non-NULL, are lists of basename
- * patterns to filter out.
- * FILTER_CALLBACK and FILTER_BATON will be called for each absolute path,
- * allowing users to further filter the list of returned entries.
- *
- * Results are returned in RESULT_POOL; use SCRATCH_POOL for temporary data.*/
-static svn_error_t *
-get_filtered_children(apr_hash_t **children,
- const char *dir_abspath,
- apr_hash_t *excludes,
- apr_array_header_t *ignores,
- apr_array_header_t *global_ignores,
- svn_client_import_filter_func_t filter_callback,
- void *filter_baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *dirents;
- apr_hash_index_t *hi;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- SVN_ERR(svn_io_get_dirents3(&dirents, dir_abspath, TRUE, result_pool,
- scratch_pool));
-
- for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
- {
- const char *base_name = svn__apr_hash_index_key(hi);
- const svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
- const char *local_abspath;
-
- svn_pool_clear(iterpool);
-
- local_abspath = svn_dirent_join(dir_abspath, base_name, iterpool);
-
- if (svn_wc_is_adm_dir(base_name, iterpool))
- {
- /* If someone's trying to import a directory named the same
- as our administrative directories, that's probably not
- what they wanted to do. If they are importing a file
- with that name, something is bound to blow up when they
- checkout what they've imported. So, just skip items with
- that name. */
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify
- = svn_wc_create_notify(svn_dirent_join(local_abspath, base_name,
- iterpool),
- svn_wc_notify_skip, iterpool);
- notify->kind = svn_node_dir;
- notify->content_state = notify->prop_state
- = svn_wc_notify_state_inapplicable;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*ctx->notify_func2)(ctx->notify_baton2, notify, iterpool);
- }
-
- apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
- continue;
- }
- /* If this is an excluded path, exclude it. */
- if (apr_hash_get(excludes, local_abspath, APR_HASH_KEY_STRING))
- {
- apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
- continue;
- }
-
- if (ignores && svn_wc_match_ignore_list(base_name, ignores, iterpool))
- {
- apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
- continue;
- }
-
- if (global_ignores &&
- svn_wc_match_ignore_list(base_name, global_ignores, iterpool))
- {
- apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
- continue;
- }
-
- if (filter_callback)
- {
- svn_boolean_t filter = FALSE;
-
- SVN_ERR(filter_callback(filter_baton, &filter, local_abspath,
- dirent, iterpool));
-
- if (filter)
- {
- apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
- continue;
- }
- }
- }
- svn_pool_destroy(iterpool);
-
- *children = dirents;
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-import_dir(svn_editor_t *editor,
- const char *local_abspath,
- const char *relpath,
- svn_depth_t depth,
- apr_hash_t *excludes,
- apr_array_header_t *global_ignores,
- svn_boolean_t no_ignore,
- svn_boolean_t no_autoprops,
- svn_boolean_t ignore_unknown_node_types,
- svn_client_import_filter_func_t filter_callback,
- void *filter_baton,
- import_ctx_t *import_ctx,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool);
-
-
-/* Import the children of DIR_ABSPATH, with other arguments similar to
- * import_dir(). */
-static svn_error_t *
-import_children(const char *dir_abspath,
- const char *dir_relpath,
- apr_hash_t *dirents,
- svn_editor_t *editor,
- svn_depth_t depth,
- apr_hash_t *excludes,
- apr_array_header_t *global_ignores,
- svn_boolean_t no_ignore,
- svn_boolean_t no_autoprops,
- svn_boolean_t ignore_unknown_node_types,
- svn_client_import_filter_func_t filter_callback,
- void *filter_baton,
- import_ctx_t *import_ctx,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- apr_array_header_t *sorted_dirents;
- int i;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- sorted_dirents = svn_sort__hash(dirents, svn_sort_compare_items_lexically,
- scratch_pool);
- for (i = 0; i < sorted_dirents->nelts; i++)
- {
- const char *local_abspath;
- const char *relpath;
- svn_sort__item_t item = APR_ARRAY_IDX(sorted_dirents, i,
- svn_sort__item_t);
- const char *base_name = item.key;
- const svn_io_dirent2_t *dirent = item.value;
-
- svn_pool_clear(iterpool);
-
- if (ctx->cancel_func)
- SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
-
- /* Typically, we started importing from ".", in which case
- edit_path is "". So below, this_path might become "./blah",
- and this_edit_path might become "blah", for example. */
- local_abspath = svn_dirent_join(dir_abspath, base_name, iterpool);
- relpath = svn_relpath_join(dir_relpath, base_name, iterpool);
-
- if (dirent->kind == svn_node_dir && depth >= svn_depth_immediates)
- {
- /* Recurse. */
- svn_depth_t depth_below_here = depth;
- if (depth == svn_depth_immediates)
- depth_below_here = svn_depth_empty;
-
- SVN_ERR(import_dir(editor, local_abspath, relpath,
- depth_below_here, excludes, global_ignores,
- no_ignore, no_autoprops,
- ignore_unknown_node_types,
- filter_callback, filter_baton,
- import_ctx, ctx, iterpool));
- }
- else if (dirent->kind == svn_node_file && depth >= svn_depth_files)
- {
- SVN_ERR(import_file(editor, local_abspath, relpath, dirent,
- import_ctx, ctx, iterpool));
- }
- else if (dirent->kind != svn_node_dir && dirent->kind != svn_node_file)
- {
- if (ignore_unknown_node_types)
- {
- /*## warn about it*/
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify
- = svn_wc_create_notify(local_abspath,
- svn_wc_notify_skip, iterpool);
- notify->kind = svn_node_dir;
- notify->content_state = notify->prop_state
- = svn_wc_notify_state_inapplicable;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*ctx->notify_func2)(ctx->notify_baton2, notify, iterpool);
- }
- }
- else
- return svn_error_createf
- (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
- _("Unknown or unversionable type for '%s'"),
- svn_dirent_local_style(local_abspath, iterpool));
- }
- }
-
- svn_pool_destroy(iterpool);
- return SVN_NO_ERROR;
-}
-
-
-/* Import directory LOCAL_ABSPATH into the repository directory indicated by
- * DIR_BATON in EDITOR. EDIT_PATH is the path imported as the root
- * directory, so all edits are relative to that.
- *
- * DEPTH is the depth at this point in the descent (it may be changed
- * for recursive calls).
- *
- * Accumulate file paths and their batons in FILES, which must be
- * non-null. (These are used to send postfix textdeltas later).
- *
- * EXCLUDES is a hash whose keys are absolute paths to exclude from
- * the import (values are unused).
- *
- * GLOBAL_IGNORES is an array of const char * ignore patterns. Any child
- * of LOCAL_ABSPATH which matches one or more of the patterns is not imported.
- *
- * If NO_IGNORE is FALSE, don't import files or directories that match
- * ignore patterns.
- *
- * If FILTER_CALLBACK is not NULL, call it with FILTER_BATON on each to be
- * imported node below LOCAL_ABSPATH to allow filtering nodes.
- *
- * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for each
- * directory.
- *
- * Use POOL for any temporary allocation. */
-static svn_error_t *
-import_dir(svn_editor_t *editor,
- const char *local_abspath,
- const char *relpath,
- svn_depth_t depth,
- apr_hash_t *excludes,
- apr_array_header_t *global_ignores,
- svn_boolean_t no_ignore,
- svn_boolean_t no_autoprops,
- svn_boolean_t ignore_unknown_node_types,
- svn_client_import_filter_func_t filter_callback,
- void *filter_baton,
- import_ctx_t *import_ctx,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
-{
- apr_hash_t *dirents;
- apr_array_header_t *children;
- apr_hash_t *props = apr_hash_make(pool);
-
- SVN_ERR(svn_path_check_valid(local_abspath, pool));
- SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes, NULL,
- global_ignores, filter_callback,
- filter_baton, ctx, pool, pool));
-
- /* Import this directory, but not yet its children. */
- SVN_ERR(svn_hash_keys(&children, dirents, pool));
- SVN_ERR(svn_editor_add_directory(editor, relpath, children, props,
- SVN_INVALID_REVNUM));
-
- /* Remember that the repository was modified */
- import_ctx->repos_changed = TRUE;
-
- /* By notifying before the recursive call below, we display
- a directory add before displaying adds underneath the
- directory. To do it the other way around, just move this
- after the recursive call. */
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify
- = svn_wc_create_notify(local_abspath, svn_wc_notify_commit_added,
- pool);
- notify->kind = svn_node_dir;
- notify->content_state = notify->prop_state
- = svn_wc_notify_state_inapplicable;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
- }
-
- /* Now import the children recursively. */
- SVN_ERR(import_children(local_abspath, relpath, dirents, editor, depth,
- excludes, global_ignores, no_ignore, no_autoprops,
- ignore_unknown_node_types,
- filter_callback, filter_baton,
- import_ctx, ctx, pool));
-
- return SVN_NO_ERROR;
-}
-
-
-/* Recursively import PATH to a repository using EDITOR and
- * EDIT_BATON. PATH can be a file or directory.
- *
- * DEPTH is the depth at which to import PATH; it behaves as for
- * svn_client_import4().
- *
- * NEW_ENTRIES is an ordered array of path components that must be
- * created in the repository (where the ordering direction is
- * parent-to-child). If PATH is a directory, NEW_ENTRIES may be empty
- * -- the result is an import which creates as many new entries in the
- * top repository target directory as there are importable entries in
- * the top of PATH; but if NEW_ENTRIES is not empty, its last item is
- * the name of a new subdirectory in the repository to hold the
- * import. If PATH is a file, NEW_ENTRIES may not be empty, and its
- * last item is the name used for the file in the repository. If
- * NEW_ENTRIES contains more than one item, all but the last item are
- * the names of intermediate directories that are created before the
- * real import begins. NEW_ENTRIES may NOT be NULL.
- *
- * EXCLUDES is a hash whose keys are absolute paths to exclude from
- * the import (values are unused).
- *
- * AUTOPROPS is hash of all config file autoprops and
- * svn:auto-props inherited by the import target, see the
- * IMPORT_CTX member of the same name.
- *
- * LOCAL_IGNORES is an array of const char * ignore patterns which
- * correspond to the svn:ignore property (if any) set on the root of the
- * repository target and thus dictates which immediate children of that
- * target should be ignored and not imported.
- *
- * GLOBAL_IGNORES is an array of const char * ignore patterns which
- * correspond to the svn:global-ignores properties (if any) set on
- * the root of the repository target or inherited by it.
- *
- * If NO_IGNORE is FALSE, don't import files or directories that match
- * ignore patterns.
- *
- * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for
- * each imported path, passing actions svn_wc_notify_commit_added.
- *
- * Use POOL for any temporary allocation.
- *
- * Note: the repository directory receiving the import was specified
- * when the editor was fetched. (I.e, when EDITOR->open_root() is
- * called, it returns a directory baton for that directory, which is
- * not necessarily the root.)
- */
-static svn_error_t *
-import(const char *local_abspath,
- const apr_array_header_t *new_entries,
- svn_editor_t *editor,
- const char *edit_relpath,
- svn_depth_t depth,
- apr_hash_t *excludes,
- apr_hash_t *autoprops,
- apr_array_header_t *local_ignores,
- apr_array_header_t *global_ignores,
- svn_boolean_t no_ignore,
- svn_boolean_t no_autoprops,
- svn_boolean_t ignore_unknown_node_types,
- svn_client_import_filter_func_t filter_callback,
- void *filter_baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
-{
- const char *relpath = edit_relpath == NULL ? "" : edit_relpath;
- import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));
- const svn_io_dirent2_t *dirent;
- apr_hash_t *props = apr_hash_make(pool);
-
- import_ctx->autoprops = autoprops;
- svn_magic__init(&import_ctx->magic_cookie, pool);
-
- /* Import a file or a directory tree. */
- SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, FALSE, pool, pool));
-
- /* Make the intermediate directory components necessary for properly
- rooting our import source tree. */
- if (new_entries->nelts)
- {
- int i;
- apr_hash_t *dirents;
-
- if (dirent->kind == svn_node_dir)
- {
- SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes,
- local_ignores, global_ignores,
- filter_callback, filter_baton,
- ctx, pool, pool));
- }
-
-
- for (i = 0; i < new_entries->nelts; i++)
- {
- apr_array_header_t *children;
- const char *component = APR_ARRAY_IDX(new_entries, i, const char *);
- relpath = svn_relpath_join(relpath, component, pool);
-
- /* If this is the last path component, and we're importing a
- file, then this component is the name of the file, not an
- intermediate directory. */
- if ((i == new_entries->nelts - 1) && (dirent->kind == svn_node_file))
- break;
-
- if (i < new_entries->nelts - 1)
- {
- children = apr_array_make(pool, 1, sizeof(const char *));
- APR_ARRAY_PUSH(children, const char *) =
- APR_ARRAY_IDX(new_entries, i + 1, const char *);
- }
- else
- SVN_ERR(svn_hash_keys(&children, dirents, pool));
-
- SVN_ERR(svn_editor_add_directory(editor, relpath, children, props,
- SVN_INVALID_REVNUM));
-
- /* Remember that the repository was modified */
- import_ctx->repos_changed = TRUE;
- }
- }
- else if (dirent->kind == svn_node_file)
- {
- return svn_error_create
- (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
- _("New entry name required when importing a file"));
- }
-
- /* Note that there is no need to check whether PATH's basename is
- the same name that we reserve for our administrative
- subdirectories. It would be strange -- though not illegal -- to
- import the contents of a directory of that name, because the
- directory's own name is not part of those contents. Of course,
- if something underneath it also has our reserved name, then we'll
- error. */
-
- if (dirent->kind == svn_node_file)
- {
- /* This code path ignores EXCLUDES and FILTER, but they don't make
- much sense for a single file import anyway. */
- svn_boolean_t ignores_match = FALSE;
-
- if (!no_ignore)
- ignores_match =
- (svn_wc_match_ignore_list(local_abspath, global_ignores, pool)
- || svn_wc_match_ignore_list(local_abspath, local_ignores, pool));
-
- if (!ignores_match)
- SVN_ERR(import_file(editor, local_abspath, relpath,
- dirent, import_ctx, ctx, pool));
- }
- else if (dirent->kind == svn_node_dir)
- {
- apr_hash_t *dirents;
-
- /* If we are creating a new repository directory path to import to,
- then we disregard any svn:ignore property. */
- if (!no_ignore && new_entries->nelts)
- local_ignores = NULL;
-
- SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes,
- local_ignores, global_ignores,
- filter_callback, filter_baton, ctx,
- pool, pool));
-
- SVN_ERR(import_children(local_abspath, relpath, dirents, editor,
- depth, excludes, global_ignores, no_ignore,
- no_autoprops, ignore_unknown_node_types,
- filter_callback, filter_baton,
- import_ctx, ctx, pool));
-
- }
- else if (dirent->kind == svn_node_none
- || dirent->kind == svn_node_unknown)
- {
- return svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
- _("'%s' does not exist"),
- svn_dirent_local_style(local_abspath, pool));
- }
-
- /* Close up shop; it's time to go home. */
- if (import_ctx->repos_changed)
- return svn_error_trace(svn_editor_complete(editor));
- else
- return svn_error_trace(svn_editor_abort(editor));
-}
-
-
struct capture_baton_t {
svn_commit_callback2_t original_callback;
void *original_baton;
@@ -735,210 +135,6 @@ get_ra_editor(svn_editor_t **editor,
/*** Public Interfaces. ***/
-svn_error_t *
-svn_client_import5(const char *path,
- const char *url,
- svn_depth_t depth,
- svn_boolean_t no_ignore,
- svn_boolean_t no_autoprops,
- svn_boolean_t ignore_unknown_node_types,
- const apr_hash_t *revprop_table,
- svn_client_import_filter_func_t filter_callback,
- void *filter_baton,
- svn_commit_callback2_t commit_callback,
- void *commit_baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- svn_error_t *err = SVN_NO_ERROR;
- const char *log_msg = "";
- svn_editor_t *editor;
- svn_ra_session_t *ra_session;
- apr_hash_t *excludes = apr_hash_make(scratch_pool);
- svn_node_kind_t kind;
- const char *local_abspath;
- apr_array_header_t *new_entries = apr_array_make(scratch_pool, 4,
- sizeof(const char *));
- const char *temp;
- const char *dir;
- apr_hash_t *commit_revprops;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- apr_hash_t *autoprops = NULL;
- apr_array_header_t *global_ignores;
- apr_hash_t *local_ignores_hash;
- apr_array_header_t *local_ignores_arr;
- const char *edit_relpath;
- const char *repos_root;
-
- if (svn_path_is_url(path))
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("'%s' is not a local path"), path);
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-
- /* Create a new commit item and add it to the array. */
- if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
- {
- /* If there's a log message gatherer, create a temporary commit
- item array solely to help generate the log message. The
- array is not used for the import itself. */
- svn_client_commit_item3_t *item;
- const char *tmp_file;
- apr_array_header_t *commit_items
- = apr_array_make(scratch_pool, 1, sizeof(item));
-
- item = svn_client_commit_item3_create(scratch_pool);
- item->path = apr_pstrdup(scratch_pool, path);
- item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
- APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
-
- SVN_ERR(svn_client__get_log_msg(&log_msg, &tmp_file, commit_items,
- ctx, scratch_pool));
- if (! log_msg)
- return SVN_NO_ERROR;
- if (tmp_file)
- {
- const char *abs_path;
- SVN_ERR(svn_dirent_get_absolute(&abs_path, tmp_file, scratch_pool));
- apr_hash_set(excludes, abs_path, APR_HASH_KEY_STRING, (void *)1);
- }
- }
-
- SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
-
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, url, NULL,
- NULL, FALSE, TRUE, ctx,
- scratch_pool));
-
- /* Figure out all the path components we need to create just to have
- a place to stick our imported tree. */
- SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
- iterpool));
-
- /* We can import into directories, but if a file already exists, that's
- an error. */
- if (kind == svn_node_file)
- return svn_error_createf
- (SVN_ERR_ENTRY_EXISTS, NULL,
- _("Path '%s' already exists"), url);
-
- while (kind == svn_node_none)
- {
- svn_pool_clear(iterpool);
-
- svn_uri_split(&temp, &dir, url, scratch_pool);
- APR_ARRAY_PUSH(new_entries, const char *) = dir;
- url = temp;
- SVN_ERR(svn_ra_reparent(ra_session, url, iterpool));
-
- SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
- iterpool));
- }
-
- /* Reverse the order of the components we added to our NEW_ENTRIES array. */
- if (new_entries->nelts)
- {
- int i, j;
- const char *component;
- for (i = 0; i < (new_entries->nelts / 2); i++)
- {
- j = new_entries->nelts - i - 1;
- component =
- APR_ARRAY_IDX(new_entries, i, const char *);
- APR_ARRAY_IDX(new_entries, i, const char *) =
- APR_ARRAY_IDX(new_entries, j, const char *);
- APR_ARRAY_IDX(new_entries, j, const char *) =
- component;
- }
- }
-
- /* The repository doesn't know about the reserved administrative
- directory. */
- if (new_entries->nelts
- /* What's this, what's this? This assignment is here because we
- use the value to construct the error message just below. It
- may not be aesthetically pleasing, but it's less ugly than
- calling APR_ARRAY_IDX twice. */
- && svn_wc_is_adm_dir(temp = APR_ARRAY_IDX(new_entries,
- new_entries->nelts - 1,
- const char *),
- scratch_pool))
- return svn_error_createf
- (SVN_ERR_CL_ADM_DIR_RESERVED, NULL,
- _("'%s' is a reserved name and cannot be imported"),
- svn_dirent_local_style(temp, scratch_pool));
-
- SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
- log_msg, ctx, scratch_pool));
-
- /* Fetch RA commit editor. */
- SVN_ERR(svn_ra__get_commit_ev2(&editor, ra_session,
- commit_revprops, commit_callback,
- commit_baton, NULL, TRUE,
- NULL, NULL, NULL, NULL,
- scratch_pool, scratch_pool));
-
- /* Get inherited svn:auto-props, svn:global-ignores, and
- svn:ignores for the location we are importing to. */
- if (!no_autoprops)
- SVN_ERR(svn_client__get_all_auto_props(&autoprops, url, ctx,
- scratch_pool, iterpool));
- if (no_ignore)
- {
- global_ignores = NULL;
- local_ignores_arr = NULL;
- }
- else
- {
- svn_opt_revision_t rev;
- apr_array_header_t *config_ignores;
-
- SVN_ERR(svn_client__get_inherited_ignores(&global_ignores, url, ctx,
- scratch_pool, iterpool));
- SVN_ERR(svn_wc_get_default_ignores(&config_ignores, ctx->config,
- scratch_pool));
- global_ignores = apr_array_append(scratch_pool, global_ignores,
- config_ignores);
-
- rev.kind = svn_opt_revision_head;
- SVN_ERR(svn_client_propget5(&local_ignores_hash, NULL, SVN_PROP_IGNORE, url,
- &rev, &rev, NULL, svn_depth_empty, NULL, ctx,
- scratch_pool, scratch_pool));
- local_ignores_arr = apr_array_make(scratch_pool, 1, sizeof(const char *));
-
- if (apr_hash_count(local_ignores_hash))
- {
- svn_string_t *propval = apr_hash_get(local_ignores_hash, url,
- APR_HASH_KEY_STRING);
- if (propval)
- {
- svn_cstring_split_append(local_ignores_arr, propval->data,
- "\n\r\t\v ", FALSE, scratch_pool);
- }
- }
- }
-
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, scratch_pool));
- edit_relpath = svn_uri_skip_ancestor(repos_root, url, scratch_pool);
-
- /* If an error occurred during the commit, abort the edit and return
- the error. We don't even care if the abort itself fails. */
- if ((err = import(local_abspath, new_entries, editor, edit_relpath,
- depth, excludes,
- autoprops, local_ignores_arr, global_ignores,
- no_ignore, no_autoprops, ignore_unknown_node_types,
- filter_callback, filter_baton, ctx, iterpool)))
- {
- svn_error_clear(svn_editor_abort(editor));
- return svn_error_trace(err);
- }
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-
static svn_error_t *
reconcile_errors(svn_error_t *commit_err,
svn_error_t *unlock_err,
Copied: subversion/branches/ev2-export/subversion/libsvn_client/import.c (from r1421408, subversion/trunk/subversion/libsvn_client/import.c)
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/import.c?p2=subversion/branches/ev2-export/subversion/libsvn_client/import.c&p1=subversion/trunk/subversion/libsvn_client/import.c&r1=1421408&r2=1421631&rev=1421631&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/import.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/import.c Fri Dec 14 01:24:55 2012
@@ -43,6 +43,7 @@
#include "svn_path.h"
#include "svn_io.h"
#include "svn_sorts.h"
+#include "svn_hash.h"
#include "svn_props.h"
#include "client.h"
@@ -83,107 +84,6 @@ typedef struct import_ctx_t
} import_ctx_t;
-/* Apply LOCAL_ABSPATH's contents (as a delta against the empty string) to
- FILE_BATON in EDITOR. Use POOL for any temporary allocation.
- PROPERTIES is the set of node properties set on this file.
-
- Fill DIGEST with the md5 checksum of the sent file; DIGEST must be
- at least APR_MD5_DIGESTSIZE bytes long. */
-
-/* ### how does this compare against svn_wc_transmit_text_deltas2() ??? */
-
-static svn_error_t *
-send_file_contents(const char *local_abspath,
- void *file_baton,
- const svn_delta_editor_t *editor,
- apr_hash_t *properties,
- unsigned char *digest,
- apr_pool_t *pool)
-{
- svn_stream_t *contents;
- svn_txdelta_window_handler_t handler;
- void *handler_baton;
- const svn_string_t *eol_style_val = NULL, *keywords_val = NULL;
- svn_boolean_t special = FALSE;
- svn_subst_eol_style_t eol_style;
- const char *eol;
- apr_hash_t *keywords;
-
- /* If there are properties, look for EOL-style and keywords ones. */
- if (properties)
- {
- eol_style_val = apr_hash_get(properties, SVN_PROP_EOL_STYLE,
- sizeof(SVN_PROP_EOL_STYLE) - 1);
- keywords_val = apr_hash_get(properties, SVN_PROP_KEYWORDS,
- sizeof(SVN_PROP_KEYWORDS) - 1);
- if (apr_hash_get(properties, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING))
- special = TRUE;
- }
-
- /* Get an editor func that wants to consume the delta stream. */
- SVN_ERR(editor->apply_textdelta(file_baton, NULL, pool,
- &handler, &handler_baton));
-
- if (eol_style_val)
- svn_subst_eol_style_from_value(&eol_style, &eol, eol_style_val->data);
- else
- {
- eol = NULL;
- eol_style = svn_subst_eol_style_none;
- }
-
- if (keywords_val)
- SVN_ERR(svn_subst_build_keywords2(&keywords, keywords_val->data,
- APR_STRINGIFY(SVN_INVALID_REVNUM),
- "", 0, "", pool));
- else
- keywords = NULL;
-
- if (special)
- {
- SVN_ERR(svn_subst_read_specialfile(&contents, local_abspath,
- pool, pool));
- }
- else
- {
- /* Open the working copy file. */
- SVN_ERR(svn_stream_open_readonly(&contents, local_abspath, pool, pool));
-
- /* If we have EOL styles or keywords, then detranslate the file. */
- if (svn_subst_translation_required(eol_style, eol, keywords,
- FALSE, TRUE))
- {
- if (eol_style == svn_subst_eol_style_unknown)
- return svn_error_createf(SVN_ERR_IO_UNKNOWN_EOL, NULL,
- _("%s property on '%s' contains "
- "unrecognized EOL-style '%s'"),
- SVN_PROP_EOL_STYLE,
- svn_dirent_local_style(local_abspath,
- pool),
- eol_style_val->data);
-
- /* We're importing, so translate files with 'native' eol-style to
- * repository-normal form, not to this platform's native EOL. */
- if (eol_style == svn_subst_eol_style_native)
- eol = SVN_SUBST_NATIVE_EOL_STR;
-
- /* Wrap the working copy stream with a filter to detranslate it. */
- contents = svn_subst_stream_translated(contents,
- eol,
- TRUE /* repair */,
- keywords,
- FALSE /* expand */,
- pool);
- }
- }
-
- /* Send the file's contents to the delta-window handler. */
- return svn_error_trace(svn_txdelta_send_stream(contents, handler,
- handler_baton, digest,
- pool));
-}
-
-
/* Import file PATH as EDIT_PATH in the repository directory indicated
* by DIR_BATON in EDITOR.
*
@@ -196,28 +96,21 @@ send_file_contents(const char *local_abs
* Use POOL for any temporary allocation.
*/
static svn_error_t *
-import_file(const svn_delta_editor_t *editor,
- void *dir_baton,
+import_file(svn_editor_t *editor,
const char *local_abspath,
- const char *edit_path,
+ const char *relpath,
const svn_io_dirent2_t *dirent,
import_ctx_t *import_ctx,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- void *file_baton;
const char *mimetype = NULL;
- unsigned char digest[APR_MD5_DIGESTSIZE];
- const char *text_checksum;
- apr_hash_t* properties;
- apr_hash_index_t *hi;
+ svn_stream_t *contents;
+ svn_checksum_t *checksum;
+ apr_hash_t* properties = NULL;
SVN_ERR(svn_path_check_valid(local_abspath, pool));
- /* Add the file, using the pool from the FILES hash. */
- SVN_ERR(editor->add_file(edit_path, dir_baton, NULL, SVN_INVALID_REVNUM,
- pool, &file_baton));
-
/* Remember that the repository was modified */
import_ctx->repos_changed = TRUE;
@@ -230,19 +123,9 @@ import_file(const svn_delta_editor_t *ed
import_ctx->autoprops,
ctx, pool, pool));
}
- else
- properties = apr_hash_make(pool);
- if (properties)
- {
- for (hi = apr_hash_first(pool, properties); hi; hi = apr_hash_next(hi))
- {
- const char *pname = svn__apr_hash_index_key(hi);
- const svn_string_t *pval = svn__apr_hash_index_val(hi);
-
- SVN_ERR(editor->change_file_prop(file_baton, pname, pval, pool));
- }
- }
+ if (!properties)
+ properties = apr_hash_make(pool);
if (ctx->notify_func2)
{
@@ -261,25 +144,18 @@ import_file(const svn_delta_editor_t *ed
property and create a temporary detranslated version in order to
send to the server. */
if (dirent->special)
- {
- apr_hash_set(properties, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING,
- svn_string_create(SVN_PROP_BOOLEAN_TRUE, pool));
- SVN_ERR(editor->change_file_prop(file_baton, SVN_PROP_SPECIAL,
- apr_hash_get(properties,
- SVN_PROP_SPECIAL,
- APR_HASH_KEY_STRING),
- pool));
- }
+ apr_hash_set(properties, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING,
+ svn_string_create(SVN_PROP_BOOLEAN_TRUE, pool));
/* Now, transmit the file contents. */
- SVN_ERR(send_file_contents(local_abspath, file_baton, editor,
- properties, digest, pool));
+ SVN_ERR(svn_client__get_detranslated_stream(&contents, &checksum, NULL,
+ local_abspath, properties, TRUE,
+ pool, pool));
- /* Finally, close the file. */
- text_checksum =
- svn_checksum_to_cstring(svn_checksum__from_digest_md5(digest, pool), pool);
+ SVN_ERR(svn_editor_add_file(editor, relpath, checksum, contents, properties,
+ SVN_INVALID_REVNUM));
- return editor->close_file(file_baton, text_checksum, pool);
+ return SVN_NO_ERROR;
}
@@ -385,10 +261,9 @@ get_filtered_children(apr_hash_t **child
}
static svn_error_t *
-import_dir(const svn_delta_editor_t *editor,
- void *dir_baton,
+import_dir(svn_editor_t *editor,
const char *local_abspath,
- const char *edit_path,
+ const char *relpath,
svn_depth_t depth,
apr_hash_t *excludes,
apr_array_header_t *global_ignores,
@@ -406,10 +281,9 @@ import_dir(const svn_delta_editor_t *edi
* import_dir(). */
static svn_error_t *
import_children(const char *dir_abspath,
- const char *edit_path,
+ const char *dir_relpath,
apr_hash_t *dirents,
- const svn_delta_editor_t *editor,
- void *dir_baton,
+ svn_editor_t *editor,
svn_depth_t depth,
apr_hash_t *excludes,
apr_array_header_t *global_ignores,
@@ -430,10 +304,11 @@ import_children(const char *dir_abspath,
scratch_pool);
for (i = 0; i < sorted_dirents->nelts; i++)
{
- const char *this_abspath, *this_edit_path;
+ const char *local_abspath;
+ const char *relpath;
svn_sort__item_t item = APR_ARRAY_IDX(sorted_dirents, i,
svn_sort__item_t);
- const char *filename = item.key;
+ const char *base_name = item.key;
const svn_io_dirent2_t *dirent = item.value;
svn_pool_clear(iterpool);
@@ -444,8 +319,8 @@ import_children(const char *dir_abspath,
/* Typically, we started importing from ".", in which case
edit_path is "". So below, this_path might become "./blah",
and this_edit_path might become "blah", for example. */
- this_abspath = svn_dirent_join(dir_abspath, filename, iterpool);
- this_edit_path = svn_relpath_join(edit_path, filename, iterpool);
+ local_abspath = svn_dirent_join(dir_abspath, base_name, iterpool);
+ relpath = svn_relpath_join(dir_relpath, base_name, iterpool);
if (dirent->kind == svn_node_dir && depth >= svn_depth_immediates)
{
@@ -454,16 +329,16 @@ import_children(const char *dir_abspath,
if (depth == svn_depth_immediates)
depth_below_here = svn_depth_empty;
- SVN_ERR(import_dir(editor, dir_baton, this_abspath,
- this_edit_path, depth_below_here, excludes,
- global_ignores, no_ignore, no_autoprops,
- ignore_unknown_node_types, filter_callback,
- filter_baton, import_ctx, ctx, iterpool));
+ SVN_ERR(import_dir(editor, local_abspath, relpath,
+ depth_below_here, excludes, global_ignores,
+ no_ignore, no_autoprops,
+ ignore_unknown_node_types,
+ filter_callback, filter_baton,
+ import_ctx, ctx, iterpool));
}
else if (dirent->kind == svn_node_file && depth >= svn_depth_files)
{
- SVN_ERR(import_file(editor, dir_baton, this_abspath,
- this_edit_path, dirent,
+ SVN_ERR(import_file(editor, local_abspath, relpath, dirent,
import_ctx, ctx, iterpool));
}
else if (dirent->kind != svn_node_dir && dirent->kind != svn_node_file)
@@ -474,7 +349,7 @@ import_children(const char *dir_abspath,
if (ctx->notify_func2)
{
svn_wc_notify_t *notify
- = svn_wc_create_notify(this_abspath,
+ = svn_wc_create_notify(local_abspath,
svn_wc_notify_skip, iterpool);
notify->kind = svn_node_dir;
notify->content_state = notify->prop_state
@@ -487,7 +362,7 @@ import_children(const char *dir_abspath,
return svn_error_createf
(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
_("Unknown or unversionable type for '%s'"),
- svn_dirent_local_style(this_abspath, iterpool));
+ svn_dirent_local_style(local_abspath, iterpool));
}
}
@@ -523,10 +398,9 @@ import_children(const char *dir_abspath,
*
* Use POOL for any temporary allocation. */
static svn_error_t *
-import_dir(const svn_delta_editor_t *editor,
- void *dir_baton,
+import_dir(svn_editor_t *editor,
const char *local_abspath,
- const char *edit_path,
+ const char *relpath,
svn_depth_t depth,
apr_hash_t *excludes,
apr_array_header_t *global_ignores,
@@ -540,7 +414,8 @@ import_dir(const svn_delta_editor_t *edi
apr_pool_t *pool)
{
apr_hash_t *dirents;
- void *this_dir_baton;
+ apr_array_header_t *children;
+ apr_hash_t *props = apr_hash_make(pool);
SVN_ERR(svn_path_check_valid(local_abspath, pool));
SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes, NULL,
@@ -548,41 +423,36 @@ import_dir(const svn_delta_editor_t *edi
filter_baton, ctx, pool, pool));
/* Import this directory, but not yet its children. */
- {
- /* Add the new subdirectory, getting a descent baton from the editor. */
- SVN_ERR(editor->add_directory(edit_path, dir_baton, NULL,
- SVN_INVALID_REVNUM, pool, &this_dir_baton));
-
- /* Remember that the repository was modified */
- import_ctx->repos_changed = TRUE;
-
- /* By notifying before the recursive call below, we display
- a directory add before displaying adds underneath the
- directory. To do it the other way around, just move this
- after the recursive call. */
- if (ctx->notify_func2)
- {
- svn_wc_notify_t *notify
- = svn_wc_create_notify(local_abspath, svn_wc_notify_commit_added,
- pool);
- notify->kind = svn_node_dir;
- notify->content_state = notify->prop_state
- = svn_wc_notify_state_inapplicable;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
- }
- }
+ SVN_ERR(svn_hash_keys(&children, dirents, pool));
+ SVN_ERR(svn_editor_add_directory(editor, relpath, children, props,
+ SVN_INVALID_REVNUM));
+
+ /* Remember that the repository was modified */
+ import_ctx->repos_changed = TRUE;
+
+ /* By notifying before the recursive call below, we display
+ a directory add before displaying adds underneath the
+ directory. To do it the other way around, just move this
+ after the recursive call. */
+ if (ctx->notify_func2)
+ {
+ svn_wc_notify_t *notify
+ = svn_wc_create_notify(local_abspath, svn_wc_notify_commit_added,
+ pool);
+ notify->kind = svn_node_dir;
+ notify->content_state = notify->prop_state
+ = svn_wc_notify_state_inapplicable;
+ notify->lock_state = svn_wc_notify_lock_state_inapplicable;
+ (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
+ }
/* Now import the children recursively. */
- SVN_ERR(import_children(local_abspath, edit_path, dirents, editor,
- this_dir_baton, depth, excludes, global_ignores,
- no_ignore, no_autoprops, ignore_unknown_node_types,
+ SVN_ERR(import_children(local_abspath, relpath, dirents, editor, depth,
+ excludes, global_ignores, no_ignore, no_autoprops,
+ ignore_unknown_node_types,
filter_callback, filter_baton,
import_ctx, ctx, pool));
- /* Finally, close the sub-directory. */
- SVN_ERR(editor->close_directory(this_dir_baton, pool));
-
return SVN_NO_ERROR;
}
@@ -638,8 +508,8 @@ import_dir(const svn_delta_editor_t *edi
static svn_error_t *
import(const char *local_abspath,
const apr_array_header_t *new_entries,
- const svn_delta_editor_t *editor,
- void *edit_baton,
+ svn_editor_t *editor,
+ const char *edit_relpath,
svn_depth_t depth,
apr_hash_t *excludes,
apr_hash_t *autoprops,
@@ -653,21 +523,14 @@ import(const char *local_abspath,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- void *root_baton;
- apr_array_header_t *batons = NULL;
- const char *edit_path = "";
+ const char *relpath = edit_relpath == NULL ? "" : edit_relpath;
import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));
const svn_io_dirent2_t *dirent;
+ apr_hash_t *props = apr_hash_make(pool);
import_ctx->autoprops = autoprops;
svn_magic__init(&import_ctx->magic_cookie, pool);
- /* Get a root dir baton. We pass an invalid revnum to open_root
- to mean "base this on the youngest revision". Should we have an
- SVN_YOUNGEST_REVNUM defined for these purposes? */
- SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
- pool, &root_baton));
-
/* Import a file or a directory tree. */
SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, FALSE, pool, pool));
@@ -676,12 +539,22 @@ import(const char *local_abspath,
if (new_entries->nelts)
{
int i;
+ apr_hash_t *dirents;
+
+ if (dirent->kind == svn_node_dir)
+ {
+ SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes,
+ local_ignores, global_ignores,
+ filter_callback, filter_baton,
+ ctx, pool, pool));
+ }
+
- batons = apr_array_make(pool, new_entries->nelts, sizeof(void *));
for (i = 0; i < new_entries->nelts; i++)
{
+ apr_array_header_t *children;
const char *component = APR_ARRAY_IDX(new_entries, i, const char *);
- edit_path = svn_relpath_join(edit_path, component, pool);
+ relpath = svn_relpath_join(relpath, component, pool);
/* If this is the last path component, and we're importing a
file, then this component is the name of the file, not an
@@ -689,11 +562,17 @@ import(const char *local_abspath,
if ((i == new_entries->nelts - 1) && (dirent->kind == svn_node_file))
break;
- APR_ARRAY_PUSH(batons, void *) = root_baton;
- SVN_ERR(editor->add_directory(edit_path,
- root_baton,
- NULL, SVN_INVALID_REVNUM,
- pool, &root_baton));
+ if (i < new_entries->nelts - 1)
+ {
+ children = apr_array_make(pool, 1, sizeof(const char *));
+ APR_ARRAY_PUSH(children, const char *) =
+ APR_ARRAY_IDX(new_entries, i + 1, const char *);
+ }
+ else
+ SVN_ERR(svn_hash_keys(&children, dirents, pool));
+
+ SVN_ERR(svn_editor_add_directory(editor, relpath, children, props,
+ SVN_INVALID_REVNUM));
/* Remember that the repository was modified */
import_ctx->repos_changed = TRUE;
@@ -726,7 +605,7 @@ import(const char *local_abspath,
|| svn_wc_match_ignore_list(local_abspath, local_ignores, pool));
if (!ignores_match)
- SVN_ERR(import_file(editor, root_baton, local_abspath, edit_path,
+ SVN_ERR(import_file(editor, local_abspath, relpath,
dirent, import_ctx, ctx, pool));
}
else if (dirent->kind == svn_node_dir)
@@ -743,11 +622,11 @@ import(const char *local_abspath,
filter_callback, filter_baton, ctx,
pool, pool));
- SVN_ERR(import_children(local_abspath, edit_path, dirents, editor,
- root_baton, depth, excludes, global_ignores,
- no_ignore, no_autoprops,
- ignore_unknown_node_types, filter_callback,
- filter_baton, import_ctx, ctx, pool));
+ SVN_ERR(import_children(local_abspath, relpath, dirents, editor,
+ depth, excludes, global_ignores, no_ignore,
+ no_autoprops, ignore_unknown_node_types,
+ filter_callback, filter_baton,
+ import_ctx, ctx, pool));
}
else if (dirent->kind == svn_node_none
@@ -759,22 +638,13 @@ import(const char *local_abspath,
}
/* Close up shop; it's time to go home. */
- SVN_ERR(editor->close_directory(root_baton, pool));
- if (batons && batons->nelts)
- {
- void **baton;
- while ((baton = (void **) apr_array_pop(batons)))
- {
- SVN_ERR(editor->close_directory(*baton, pool));
- }
- }
-
if (import_ctx->repos_changed)
- return editor->close_edit(edit_baton, pool);
+ return svn_error_trace(svn_editor_complete(editor));
else
- return editor->abort_edit(edit_baton, pool);
+ return svn_error_trace(svn_editor_abort(editor));
}
+
/*** Public Interfaces. ***/
@@ -795,8 +665,7 @@ svn_client_import5(const char *path,
{
svn_error_t *err = SVN_NO_ERROR;
const char *log_msg = "";
- const svn_delta_editor_t *editor;
- void *edit_baton;
+ svn_editor_t *editor;
svn_ra_session_t *ra_session;
apr_hash_t *excludes = apr_hash_make(scratch_pool);
svn_node_kind_t kind;
@@ -811,6 +680,8 @@ svn_client_import5(const char *path,
apr_array_header_t *global_ignores;
apr_hash_t *local_ignores_hash;
apr_array_header_t *local_ignores_arr;
+ const char *edit_relpath;
+ const char *repos_root;
if (svn_path_is_url(path))
return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -914,13 +785,11 @@ svn_client_import5(const char *path,
log_msg, ctx, scratch_pool));
/* Fetch RA commit editor. */
- SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
- svn_client__get_shim_callbacks(ctx->wc_ctx,
- NULL, scratch_pool)));
- SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
- commit_revprops, commit_callback,
- commit_baton, NULL, TRUE,
- scratch_pool));
+ SVN_ERR(svn_ra__get_commit_ev2(&editor, ra_session,
+ commit_revprops, commit_callback,
+ commit_baton, NULL, TRUE,
+ NULL, NULL, NULL, NULL,
+ scratch_pool, scratch_pool));
/* Get inherited svn:auto-props, svn:global-ignores, and
svn:ignores for the location we are importing to. */
@@ -962,21 +831,22 @@ svn_client_import5(const char *path,
}
}
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, scratch_pool));
+ edit_relpath = svn_uri_skip_ancestor(repos_root, url, scratch_pool);
+
/* If an error occurred during the commit, abort the edit and return
the error. We don't even care if the abort itself fails. */
- if ((err = import(local_abspath, new_entries, editor, edit_baton,
- depth, excludes, autoprops, local_ignores_arr,
- global_ignores, no_ignore, no_autoprops,
- ignore_unknown_node_types, filter_callback,
- filter_baton, ctx, iterpool)))
- {
- return svn_error_compose_create(
- err,
- editor->abort_edit(edit_baton, iterpool));
+ if ((err = import(local_abspath, new_entries, editor, edit_relpath,
+ depth, excludes,
+ autoprops, local_ignores_arr, global_ignores,
+ no_ignore, no_autoprops, ignore_unknown_node_types,
+ filter_callback, filter_baton, ctx, iterpool)))
+ {
+ svn_error_clear(svn_editor_abort(editor));
+ return svn_error_trace(err);
}
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-