Modified: subversion/branches/tree-read-api/subversion/libsvn_client/cmdline.c URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_client/cmdline.c?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_client/cmdline.c (original) +++ subversion/branches/tree-read-api/subversion/libsvn_client/cmdline.c Sun Jan 6 02:33:34 2013 @@ -43,51 +43,6 @@ #define DEFAULT_ARRAY_SIZE 5 -/* Return true iff ARG is a repository-relative URL: specifically that - * it starts with the characters "^/". - * ARG is in UTF-8 encoding. - * Do not check whether ARG is properly URI-encoded, canonical, or valid - * in any other way. */ -static svn_boolean_t -arg_is_repos_relative_url(const char *arg) -{ - return (0 == strncmp("^/", arg, 2)); -} - -/* Set *ABSOLUTE_URL to the absolute URL represented by RELATIVE_URL - * relative to REPOS_ROOT_URL. - * *ABSOLUTE_URL will end with a peg revision specifier if RELATIVE_URL did. - * RELATIVE_URL is in repository-relative syntax: - * "^/[REL-URL][@PEG]", - * REPOS_ROOT_URL is the absolute URL of the repository root. - * All strings are in UTF-8 encoding. - * Allocate *ABSOLUTE_URL in POOL. - * - * REPOS_ROOT_URL and RELATIVE_URL do not have to be properly URI-encoded, - * canonical, or valid in any other way. The caller is expected to perform - * canonicalization on *ABSOLUTE_URL after the call to the function. - */ -static svn_error_t * -resolve_repos_relative_url(const char **absolute_url, - const char *relative_url, - const char *repos_root_url, - apr_pool_t *pool) -{ - if (! arg_is_repos_relative_url(relative_url)) - return svn_error_createf(SVN_ERR_BAD_URL, NULL, - _("Improper relative URL '%s'"), - relative_url); - - /* No assumptions are made about the canonicalization of the input - * arguments, it is presumed that the output will be canonicalized after - * this function, which will remove any duplicate path separator. - */ - *absolute_url = apr_pstrcat(pool, repos_root_url, relative_url + 1, - (char *)NULL); - - return SVN_NO_ERROR; -} - /* Attempt to find the repository root url for TARGET, possibly using CTX for * authentication. If one is found and *ROOT_URL is not NULL, then just check @@ -189,7 +144,7 @@ svn_client_args_to_target_array2(apr_arr SVN_ERR(svn_utf_cstring_to_utf8(&utf8_target, raw_target, pool)); - if (arg_is_repos_relative_url(utf8_target)) + if (svn_path_is_repos_relative_url(utf8_target)) rel_url_found = TRUE; APR_ARRAY_PUSH(input_targets, const char *) = utf8_target; @@ -204,7 +159,7 @@ svn_client_args_to_target_array2(apr_arr const char *utf8_target = APR_ARRAY_IDX(known_targets, i, const char *); - if (arg_is_repos_relative_url(utf8_target)) + if (svn_path_is_repos_relative_url(utf8_target)) rel_url_found = TRUE; APR_ARRAY_PUSH(input_targets, const char *) = utf8_target; @@ -220,7 +175,7 @@ svn_client_args_to_target_array2(apr_arr /* Relative urls will be canonicalized when they are resolved later in * the function */ - if (arg_is_repos_relative_url(utf8_target)) + if (svn_path_is_repos_relative_url(utf8_target)) { APR_ARRAY_PUSH(output_targets, const char *) = utf8_target; } @@ -367,7 +322,7 @@ svn_client_args_to_target_array2(apr_arr const char *target = APR_ARRAY_IDX(output_targets, i, const char *); - if (arg_is_repos_relative_url(target)) + if (svn_path_is_repos_relative_url(target)) { const char *abs_target; const char *true_target; @@ -376,8 +331,9 @@ svn_client_args_to_target_array2(apr_arr SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, &peg_rev, target, pool)); - SVN_ERR(resolve_repos_relative_url(&abs_target, true_target, - root_url, pool)); + SVN_ERR(svn_path_resolve_repos_relative_url(&abs_target, + true_target, + root_url, pool)); SVN_ERR(svn_opt__arg_canonicalize_url(&true_target, abs_target, pool));
Modified: subversion/branches/tree-read-api/subversion/libsvn_client/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_client/commit.c?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_client/commit.c (original) +++ subversion/branches/tree-read-api/subversion/libsvn_client/commit.c Sun Jan 6 02:33:34 2013 @@ -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,743 +39,14 @@ #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 "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; - - -/* 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. - * - * 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(const svn_delta_editor_t *editor, - void *dir_baton, - const char *local_abspath, - const char *edit_path, - 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_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; - - 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)); - } - 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 (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)); - SVN_ERR(editor->change_file_prop(file_baton, SVN_PROP_SPECIAL, - apr_hash_get(properties, - SVN_PROP_SPECIAL, - APR_HASH_KEY_STRING), - pool)); - } - - /* Now, transmit the file contents. */ - SVN_ERR(send_file_contents(local_abspath, file_baton, editor, - properties, digest, pool)); - - /* Finally, close the file. */ - text_checksum = - svn_checksum_to_cstring(svn_checksum__from_digest_md5(digest, pool), pool); - - return editor->close_file(file_baton, text_checksum, pool); -} - - -/* 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(const svn_delta_editor_t *editor, - void *dir_baton, - const char *local_abspath, - const char *edit_path, - 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 *edit_path, - apr_hash_t *dirents, - const svn_delta_editor_t *editor, - void *dir_baton, - 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 *this_abspath, *this_edit_path; - svn_sort__item_t item = APR_ARRAY_IDX(sorted_dirents, i, - svn_sort__item_t); - const char *filename = 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. */ - this_abspath = svn_dirent_join(dir_abspath, filename, iterpool); - this_edit_path = svn_relpath_join(edit_path, filename, 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, 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)); - } - else if (dirent->kind == svn_node_file && depth >= svn_depth_files) - { - SVN_ERR(import_file(editor, dir_baton, this_abspath, - this_edit_path, 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(this_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(this_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(const svn_delta_editor_t *editor, - void *dir_baton, - const char *local_abspath, - const char *edit_path, - 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; - void *this_dir_baton; - - 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. */ - { - /* 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); - } - } - - /* 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, - 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; -} - - -/* 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, - const svn_delta_editor_t *editor, - void *edit_baton, - 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) -{ - void *root_baton; - apr_array_header_t *batons = NULL; - const char *edit_path = ""; - import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx)); - const svn_io_dirent2_t *dirent; - - 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)); - - /* Make the intermediate directory components necessary for properly - rooting our import source tree. */ - if (new_entries->nelts) - { - int i; - - batons = apr_array_make(pool, new_entries->nelts, sizeof(void *)); - for (i = 0; i < new_entries->nelts; i++) - { - const char *component = APR_ARRAY_IDX(new_entries, i, const char *); - edit_path = svn_relpath_join(edit_path, 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; - - APR_ARRAY_PUSH(batons, void *) = root_baton; - SVN_ERR(editor->add_directory(edit_path, - root_baton, - NULL, SVN_INVALID_REVNUM, - pool, &root_baton)); - - /* 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, root_baton, local_abspath, edit_path, - 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, 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)); - - } - 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. */ - 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); - else - return editor->abort_edit(edit_baton, pool); -} - - struct capture_baton_t { svn_commit_callback2_t original_callback; void *original_baton; @@ -866,209 +134,6 @@ get_ra_editor(const svn_delta_editor_t * /*** 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 = ""; - const svn_delta_editor_t *editor; - void *edit_baton; - 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; - - 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__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)); - - /* 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); - } - } - } - - /* 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)); - } - - svn_pool_destroy(iterpool); - - return SVN_NO_ERROR; -} - - static svn_error_t * reconcile_errors(svn_error_t *commit_err, svn_error_t *unlock_err, @@ -1286,8 +351,8 @@ determine_lock_targets(apr_array_header_ target_abspath = svn_dirent_join(base_abspath, target_relpath, scratch_pool); - err = svn_wc__get_wc_root(&wcroot_abspath, wc_ctx, target_abspath, - iterpool, iterpool); + err = svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, target_abspath, + iterpool, iterpool); if (err) { @@ -1963,25 +1028,3 @@ svn_client_commit6(const apr_array_heade return svn_error_trace(reconcile_errors(cmt_err, unlock_err, bump_err, pool)); } - -svn_error_t * -svn_client_commit5(const apr_array_header_t *targets, - svn_depth_t depth, - svn_boolean_t keep_locks, - svn_boolean_t keep_changelists, - svn_boolean_t commit_as_operations, - const apr_array_header_t *changelists, - const apr_hash_t *revprop_table, - svn_commit_callback2_t commit_callback, - void *commit_baton, - svn_client_ctx_t *ctx, - apr_pool_t *pool) -{ - return svn_client_commit6(targets, depth, keep_locks, keep_changelists, - commit_as_operations, - TRUE, /* include_file_externals */ - FALSE, /* include_dir_externals */ - changelists, revprop_table, commit_callback, - commit_baton, ctx, pool); -} - Modified: subversion/branches/tree-read-api/subversion/libsvn_client/commit_util.c URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_client/commit_util.c?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_client/commit_util.c (original) +++ subversion/branches/tree-read-api/subversion/libsvn_client/commit_util.c Sun Jan 6 02:33:34 2013 @@ -290,8 +290,8 @@ bail_on_tree_conflicted_ancestor(svn_wc_ { const char *wcroot_abspath; - SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, wc_ctx, local_abspath, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, local_abspath, + scratch_pool, scratch_pool)); local_abspath = svn_dirent_dirname(local_abspath, scratch_pool); Modified: subversion/branches/tree-read-api/subversion/libsvn_client/delete.c URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_client/delete.c?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_client/delete.c (original) +++ subversion/branches/tree-read-api/subversion/libsvn_client/delete.c Sun Jan 6 02:33:34 2013 @@ -435,8 +435,8 @@ svn_client_delete4(const apr_array_heade APR_ARRAY_IDX(paths, i, const char *), pool)); - SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx, - local_abspath, pool, iterpool)); + SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx, + local_abspath, pool, iterpool)); targets = apr_hash_get(wcroots, wcroot_abspath, APR_HASH_KEY_STRING); if (targets == NULL) Modified: subversion/branches/tree-read-api/subversion/libsvn_client/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_client/deprecated.c?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_client/deprecated.c (original) +++ subversion/branches/tree-read-api/subversion/libsvn_client/deprecated.c Sun Jan 6 02:33:34 2013 @@ -512,6 +512,26 @@ downgrade_commit_copied_notify_func(void b->orig_notify_func2(b->orig_notify_baton2, notify, pool); } +svn_error_t * +svn_client_commit5(const apr_array_header_t *targets, + svn_depth_t depth, + svn_boolean_t keep_locks, + svn_boolean_t keep_changelists, + svn_boolean_t commit_as_operations, + const apr_array_header_t *changelists, + const apr_hash_t *revprop_table, + svn_commit_callback2_t commit_callback, + void *commit_baton, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + return svn_client_commit6(targets, depth, keep_locks, keep_changelists, + commit_as_operations, + FALSE, /* include_file_externals */ + FALSE, /* include_dir_externals */ + changelists, revprop_table, commit_callback, + commit_baton, ctx, pool); +} svn_error_t * svn_client_commit4(svn_commit_info_t **commit_info_p,
