Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/hotcopy.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/hotcopy.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/hotcopy.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/hotcopy.c Wed Mar 4 15:56:18 2015 @@ -855,7 +855,6 @@ hotcopy_body(void *baton, apr_pool_t *po * ### so we have no way of just printing a warning via * ### the fs->warning() callback. */ - const char *msg; const char *src_abspath; const char *dst_abspath; const char *config_relpath; @@ -874,13 +873,12 @@ hotcopy_body(void *baton, apr_pool_t *po src_abspath = svn_dirent_dirname(src_abspath, pool); dst_abspath = svn_dirent_dirname(dst_abspath, pool); - msg = apr_psprintf(pool, + return svn_error_quick_wrapf(err, _("Failed to create hotcopy at '%s'. " "The file '%s' is missing from the source " "repository. Please create this file, for " "instance by running 'svnadmin upgrade %s'"), dst_abspath, config_relpath, src_abspath); - return svn_error_quick_wrap(err, msg); } else return svn_error_trace(err);
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/commit.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/commit.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/commit.c Wed Mar 4 15:56:18 2015 @@ -101,6 +101,8 @@ typedef struct delete_context_t { svn_revnum_t revision; commit_context_t *commit_ctx; + + svn_boolean_t non_recursive_if; /* Only create a non-recursive If header */ } delete_context_t; /* Represents a directory. */ @@ -1101,8 +1103,15 @@ setup_delete_headers(serf_bucket_t *head serf_bucket_headers_set(headers, SVN_DAV_VERSION_NAME_HEADER, apr_ltoa(pool, del->revision)); - SVN_ERR(setup_if_header_recursive(&added, headers, del->commit_ctx, - del->relpath, pool)); + if (! del->non_recursive_if) + SVN_ERR(setup_if_header_recursive(&added, headers, del->commit_ctx, + del->relpath, pool)); + else + { + SVN_ERR(maybe_set_lock_token_header(headers, del->commit_ctx, + del->relpath, pool)); + added = TRUE; + } if (added && del->commit_ctx->keep_locks) serf_bucket_headers_setn(headers, SVN_DAV_OPTIONS_HEADER, @@ -1402,6 +1411,28 @@ open_root(void *edit_baton, return SVN_NO_ERROR; } +/* Implements svn_ra_serf__request_body_delegate_t */ +static svn_error_t * +create_delete_body(serf_bucket_t **body_bkt, + void *baton, + serf_bucket_alloc_t *alloc, + apr_pool_t *pool /* request pool */, + apr_pool_t *scratch_pool) +{ + delete_context_t *ctx = baton; + serf_bucket_t *body; + + body = serf_bucket_aggregate_create(alloc); + + svn_ra_serf__add_xml_header_buckets(body, alloc); + + svn_ra_serf__merge_lock_token_list(ctx->commit_ctx->lock_tokens, + ctx->relpath, body, alloc, pool); + + *body_bkt = body; + return SVN_NO_ERROR; +} + static svn_error_t * delete_entry(const char *path, svn_revnum_t revision, @@ -1412,6 +1443,7 @@ delete_entry(const char *path, delete_context_t *delete_ctx; svn_ra_serf__handler_t *handler; const char *delete_target; + svn_error_t *err; if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx)) { @@ -1446,7 +1478,23 @@ delete_entry(const char *path, handler->method = "DELETE"; handler->path = delete_target; - SVN_ERR(svn_ra_serf__context_run_one(handler, pool)); + err = svn_ra_serf__context_run_one(handler, pool); + if (err && err->apr_err == SVN_ERR_RA_DAV_REQUEST_FAILED + && handler->sline.code == 400) + { + svn_error_clear(err); + + /* Try again with non-standard body to overcome Apache Httpd + header limit */ + delete_ctx->non_recursive_if = TRUE; + handler->body_type = "text/xml"; + handler->body_delegate = create_delete_body; + handler->body_delegate_baton = delete_ctx; + + SVN_ERR(svn_ra_serf__context_run_one(handler, pool)); + } + else + SVN_ERR(err); /* 204 No Content: item successfully deleted */ if (handler->sline.code != 204) @@ -1539,7 +1587,9 @@ add_directory(const char *path, handler->header_delegate = setup_copy_dir_headers; handler->header_delegate_baton = dir; } - + /* We have the same problem as with DELETE here: if there are too many + locks, the request fails. But in this case there is no way to retry + with a non-standard request. #### How to fix? */ SVN_ERR(svn_ra_serf__context_run_one(handler, dir->pool)); if (handler->sline.code != 201) Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/merge.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/merge.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/merge.c Wed Mar 4 15:56:18 2015 @@ -285,12 +285,12 @@ setup_merge_headers(serf_bucket_t *heade return SVN_NO_ERROR; } -static void -merge_lock_token_list(apr_hash_t *lock_tokens, - const char *parent, - serf_bucket_t *body, - serf_bucket_alloc_t *alloc, - apr_pool_t *pool) +void +svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens, + const char *parent, + serf_bucket_t *body, + serf_bucket_alloc_t *alloc, + apr_pool_t *pool) { apr_hash_index_t *hi; @@ -378,7 +378,8 @@ create_merge_body(serf_bucket_t **bkt, "D:creator-displayname", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop"); - merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt, alloc, pool); + svn_ra_serf__merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt, + alloc, pool); svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:merge"); Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/ra_serf.h URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/ra_serf.h?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/ra_serf.h (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/ra_serf.h Wed Mar 4 15:56:18 2015 @@ -1021,6 +1021,13 @@ svn_ra_serf__svnname_from_wirename(const /** MERGE-related functions **/ +void +svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens, + const char *parent, + serf_bucket_t *body, + serf_bucket_alloc_t *alloc, + apr_pool_t *pool); + /* Create an MERGE request aimed at the SESSION url, requesting the merge of the resource identified by MERGE_RESOURCE_URL. LOCK_TOKENS is a hash mapping paths to lock tokens owned by the Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c Wed Mar 4 15:56:18 2015 @@ -633,7 +633,7 @@ static svn_error_t *ra_svn_handle_close_ /* Close the directory and destroy the baton. */ SVN_CMD_ERR(ds->editor->close_directory(entry->baton, pool)); - svn_hash_sets(ds->tokens, token, NULL); + apr_hash_set(ds->tokens, token->data, token->len, NULL); svn_pool_destroy(entry->pool); return SVN_NO_ERROR; } @@ -812,7 +812,7 @@ static svn_error_t *ra_svn_handle_close_ /* Close the file and destroy the baton. */ SVN_CMD_ERR(ds->editor->close_file(entry->baton, text_checksum, pool)); - svn_hash_sets(ds->tokens, token, NULL); + apr_hash_set(ds->tokens, token->data, token->len, NULL); if (--ds->file_refs == 0) svn_pool_clear(ds->file_pool); return SVN_NO_ERROR; Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/cmdline.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/cmdline.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/cmdline.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/cmdline.c Wed Mar 4 15:56:18 2015 @@ -1200,12 +1200,12 @@ svn_cmdline__edit_string_externally(svn_ apr_file_t *tmp_file; const char *tmpfile_name; const char *tmpfile_native; - const char *tmpfile_apr, *base_dir_apr; + const char *base_dir_apr; svn_string_t *translated_contents; - apr_status_t apr_err, apr_err2; + apr_status_t apr_err; apr_size_t written; apr_finfo_t finfo_before, finfo_after; - svn_error_t *err = SVN_NO_ERROR, *err2; + svn_error_t *err = SVN_NO_ERROR; char *old_cwd; int sys_err; svn_boolean_t remove_file = TRUE; @@ -1288,49 +1288,36 @@ svn_cmdline__edit_string_externally(svn_ the file we just created!! ***/ /* Dump initial CONTENTS to TMP_FILE. */ - apr_err = apr_file_write_full(tmp_file, translated_contents->data, - translated_contents->len, &written); + err = svn_io_file_write_full(tmp_file, translated_contents->data, + translated_contents->len, &written, + pool); - apr_err2 = apr_file_close(tmp_file); - if (! apr_err) - apr_err = apr_err2; + err = svn_error_compose_create(err, svn_io_file_close(tmp_file, pool)); /* Make sure the whole CONTENTS were written, else return an error. */ - if (apr_err) - { - err = svn_error_wrap_apr(apr_err, _("Can't write to '%s'"), - tmpfile_name); - goto cleanup; - } - - err = svn_path_cstring_from_utf8(&tmpfile_apr, tmpfile_name, pool); if (err) goto cleanup; /* Get information about the temporary file before the user has been allowed to edit its contents. */ - apr_err = apr_stat(&finfo_before, tmpfile_apr, - APR_FINFO_MTIME, pool); - if (apr_err) - { - err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name); - goto cleanup; - } + err = svn_io_stat(&finfo_before, tmpfile_name, APR_FINFO_MTIME, pool); + if (err) + goto cleanup; /* Backdate the file a little bit in case the editor is very fast and doesn't change the size. (Use two seconds, since some filesystems have coarse granularity.) It's OK if this call fails, so we don't check its return value.*/ - apr_file_mtime_set(tmpfile_apr, finfo_before.mtime - 2000, pool); + err = svn_io_set_file_affected_time(finfo_before.mtime + - apr_time_from_sec(2), + tmpfile_name, pool); + svn_error_clear(err); /* Stat it again to get the mtime we actually set. */ - apr_err = apr_stat(&finfo_before, tmpfile_apr, - APR_FINFO_MTIME | APR_FINFO_SIZE, pool); - if (apr_err) - { - err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name); - goto cleanup; - } + err = svn_io_stat(&finfo_before, tmpfile_name, + APR_FINFO_MTIME | APR_FINFO_SIZE, pool); + if (err) + goto cleanup; /* Prepare the editor command line. */ err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool); @@ -1358,13 +1345,10 @@ svn_cmdline__edit_string_externally(svn_ } /* Get information about the temporary file after the assumed editing. */ - apr_err = apr_stat(&finfo_after, tmpfile_apr, - APR_FINFO_MTIME | APR_FINFO_SIZE, pool); - if (apr_err) - { - err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name); - goto cleanup; - } + err = svn_io_stat(&finfo_after, tmpfile_name, + APR_FINFO_MTIME | APR_FINFO_SIZE, pool); + if (err) + goto cleanup; /* If the file looks changed... */ if ((finfo_before.mtime != finfo_after.mtime) || @@ -1402,13 +1386,9 @@ svn_cmdline__edit_string_externally(svn_ if (remove_file) { /* Remove the file from disk. */ - err2 = svn_io_remove_file2(tmpfile_name, FALSE, pool); - - /* Only report remove error if there was no previous error. */ - if (! err && err2) - err = err2; - else - svn_error_clear(err2); + err = svn_error_compose_create( + err, + svn_io_remove_file2(tmpfile_name, FALSE, pool)); } cleanup2: Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/error.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/error.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/error.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/error.c Wed Mar 4 15:56:18 2015 @@ -28,6 +28,10 @@ #include <apr_pools.h> #include <apr_strings.h> +#if defined(SVN_DEBUG) && APR_HAS_THREADS +#include <apr_thread_proc.h> +#endif + #include <zlib.h> #ifndef SVN_ERR__TRACING @@ -38,12 +42,56 @@ #include "svn_pools.h" #include "svn_utf.h" +#include "private/svn_error_private.h" +#include "svn_private_config.h" + +#if defined(SVN_DEBUG) && APR_HAS_THREADS +#include "private/svn_atomic.h" +#include "pools.h" +#endif + + #ifdef SVN_DEBUG -/* XXX FIXME: These should be protected by a thread mutex. - svn_error__locate and make_error_internal should cooperate - in locking and unlocking it. */ +# if APR_HAS_THREADS +static apr_threadkey_t *error_file_key = NULL; +static apr_threadkey_t *error_line_key = NULL; + +/* No-op destructor for apr_threadkey_private_create(). */ +static void null_threadkey_dtor(void *stuff) {} + +/* Handler for svn_atomic__init_once used by svn_error__locate to + initialize the thread-local error location storage. + This function will never return an error. */ +static svn_error_t * +locate_init_once(void *ignored_baton, apr_pool_t *ignored_pool) +{ + /* Strictly speaking, this is a memory leak, since we're creating an + unmanaged, top-level pool and never destroying it. We do this + because this pool controls the lifetime of the thread-local + storage for error locations, and that storage must always be + available. */ + apr_pool_t *threadkey_pool = svn_pool__create_unmanaged(TRUE); + apr_status_t status; + + status = apr_threadkey_private_create(&error_file_key, + null_threadkey_dtor, + threadkey_pool); + if (status == APR_SUCCESS) + status = apr_threadkey_private_create(&error_line_key, + null_threadkey_dtor, + threadkey_pool); + + /* If anything went wrong with the creation of the thread-local + storage, we'll revert to the old, thread-agnostic behaviour */ + if (status != APR_SUCCESS) + error_file_key = error_line_key = NULL; + + return SVN_NO_ERROR; +} +# endif /* APR_HAS_THREADS */ -/* XXX TODO: Define mutex here #if APR_HAS_THREADS */ +/* These location variables will be used in no-threads mode or if + thread-local storage is not available. */ static const char * volatile error_file = NULL; static long volatile error_line = -1; @@ -51,9 +99,6 @@ static long volatile error_line = -1; static const char SVN_FILE_LINE_UNDEFINED[] = "svn:<undefined>"; #endif /* SVN_DEBUG */ -#include "svn_private_config.h" -#include "private/svn_error_private.h" - /* * Undefine the helpers for creating errors. @@ -67,6 +112,7 @@ static const char SVN_FILE_LINE_UNDEFINE #undef svn_error_create #undef svn_error_createf #undef svn_error_quick_wrap +#undef svn_error_quick_wrapf #undef svn_error_wrap_apr /* Note: Although this is a "__" function, it was historically in the @@ -75,11 +121,27 @@ static const char SVN_FILE_LINE_UNDEFINE void svn_error__locate(const char *file, long line) { -#if defined(SVN_DEBUG) - /* XXX TODO: Lock mutex here */ +#ifdef SVN_DEBUG +# if APR_HAS_THREADS + static volatile svn_atomic_t init_status = 0; + svn_error_clear(svn_atomic__init_once(&init_status, + locate_init_once, + NULL, NULL)); + + if (error_file_key && error_line_key) + { + apr_status_t status; + status = apr_threadkey_private_set((char*)file, error_file_key); + if (status == APR_SUCCESS) + status = apr_threadkey_private_set((void*)line, error_line_key); + if (status == APR_SUCCESS) + return; + } +# endif /* APR_HAS_THREADS */ + error_file = file; error_line = line; -#endif +#endif /* SVN_DEBUG */ } @@ -102,6 +164,7 @@ make_error_internal(apr_status_t apr_err { apr_pool_t *pool; svn_error_t *new_error; + apr_status_t status = APR_SUCCESS; /* Reuse the child's pool, or create our own. */ if (child) @@ -120,16 +183,34 @@ make_error_internal(apr_status_t apr_err new_error->apr_err = apr_err; new_error->child = child; new_error->pool = pool; -#if defined(SVN_DEBUG) - new_error->file = error_file; - new_error->line = error_line; - /* XXX TODO: Unlock mutex here */ + +#ifdef SVN_DEBUG +#if APR_HAS_THREADS + if (error_file_key && error_line_key) + { + void *item; + status = apr_threadkey_private_get(&item, error_file_key); + if (status == APR_SUCCESS) + { + new_error->file = item; + status = apr_threadkey_private_get(&item, error_line_key); + if (status == APR_SUCCESS) + new_error->line = (long)item; + } + } +# endif /* APR_HAS_THREADS */ + + if (status != APR_SUCCESS) + { + new_error->file = error_file; + new_error->line = error_line; + } if (! child) apr_pool_cleanup_register(pool, new_error, err_abort, apr_pool_cleanup_null); -#endif +#endif /* SVN_DEBUG */ return new_error; } @@ -224,6 +305,26 @@ svn_error_quick_wrap(svn_error_t *child, new_msg); } +svn_error_t * +svn_error_quick_wrapf(svn_error_t *child, + const char *fmt, + ...) +{ + svn_error_t *err; + va_list ap; + + if (child == SVN_NO_ERROR) + return SVN_NO_ERROR; + + err = make_error_internal(child->apr_err, child); + + va_start(ap, fmt); + err->message = apr_pvsprintf(err->pool, fmt, ap); + va_end(ap); + + return err; +} + /* Messages in tracing errors all point to this static string. */ static const char error_tracing_link[] = "traced call"; @@ -557,10 +658,6 @@ svn_handle_error2(svn_error_t *err, apr_array_header_t *empties; svn_error_t *tmp_err; - /* ### The rest of this file carefully avoids using svn_pool_*(), - preferring apr_pool_*() instead. I can't remember why -- it may - be an artifact of r843793, or it may be for some deeper reason -- - but I'm playing it safe and using apr_pool_*() here too. */ subpool = svn_pool_create(err->pool); empties = apr_array_make(subpool, 0, sizeof(apr_status_t)); Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/hash.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/hash.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/hash.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/hash.c Wed Mar 4 15:56:18 2015 @@ -31,10 +31,14 @@ #include <apr_hash.h> #include <apr_file_io.h> +#ifndef SVN_HASH__GETS_SETS +#define SVN_HASH__GETS_SETS +#endif +#include "svn_hash.h" + #include "svn_types.h" #include "svn_string.h" #include "svn_error.h" -#include "svn_hash.h" #include "svn_sorts.h" #include "svn_io.h" #include "svn_pools.h" @@ -45,7 +49,6 @@ #include "svn_private_config.h" - /* @@ -560,6 +563,20 @@ svn_hash_from_cstring_keys(apr_hash_t ** } +void * +svn_hash__gets(apr_hash_t *ht, const char *key) +{ + return apr_hash_get(ht, key, APR_HASH_KEY_STRING); +} + + +void +svn_hash__sets(apr_hash_t *ht, const char *key, const void *val) +{ + apr_hash_set(ht, key, APR_HASH_KEY_STRING, val); +} + + /*** Specialized getter APIs ***/ Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c Wed Mar 4 15:56:18 2015 @@ -1002,10 +1002,9 @@ svn_io_copy_perms(const char *src, svn_error_clear(err); else { - const char *message; - message = apr_psprintf(pool, _("Can't set permissions on '%s'"), - svn_dirent_local_style(dst, pool)); - return svn_error_quick_wrap(err, message); + return svn_error_quick_wrapf( + err, _("Can't set permissions on '%s'"), + svn_dirent_local_style(dst, pool)); } } } @@ -5080,12 +5079,9 @@ svn_io_open_unique_file3(apr_file_t **fi svn_error_clear(err); else { - const char *message; - message = apr_psprintf(scratch_pool, - _("Can't set permissions on '%s'"), - svn_dirent_local_style(tempname, - scratch_pool)); - return svn_error_quick_wrap(err, message); + return svn_error_quick_wrapf( + err, _("Can't set permissions on '%s'"), + svn_dirent_local_style(tempname, scratch_pool)); } } } Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/pool.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/pool.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/pool.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/pool.c Wed Mar 4 15:56:18 2015 @@ -26,12 +26,15 @@ #include <stdlib.h> #include <stdio.h> +#include <apr.h> +#include <apr_version.h> #include <apr_general.h> #include <apr_pools.h> #include <apr_thread_mutex.h> #include "svn_pools.h" +#include "pools.h" #if APR_POOL_DEBUG /* file_line for the non-debug case. */ @@ -140,3 +143,24 @@ svn_pool_create_allocator(svn_boolean_t return allocator; } + + +/* + * apr_pool_create_core_ex was introduced in APR 1.3.0, then + * deprecated and renamed to apr_pool_create_unmanaged_ex in 1.3.3. + * Since our minimum requirement is APR 1.3.0, one or the other of + * these functions will always be available. + */ +#if !APR_VERSION_AT_LEAST(1,3,3) +#define apr_pool_create_unmanaged_ex apr_pool_create_core_ex +#endif + +/* Private function that creates an unmanaged pool. */ +apr_pool_t * +svn_pool__create_unmanaged(svn_boolean_t thread_safe) +{ + apr_pool_t *pool; + apr_pool_create_unmanaged_ex(&pool, abort_on_pool_failure, + svn_pool_create_allocator(thread_safe)); + return pool; +} Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/sqlite.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/sqlite.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/sqlite.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/sqlite.c Wed Mar 4 15:56:18 2015 @@ -1307,7 +1307,7 @@ svn_sqlite__finish_transaction(svn_sqlit err2 = get_internal_statement(&stmt, db, STMT_INTERNAL_ROLLBACK_TRANSACTION); if (!err2) - err2 = svn_sqlite__step_done(stmt); + err2 = svn_error_trace(svn_sqlite__step_done(stmt)); if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY) { @@ -1330,14 +1330,14 @@ svn_sqlite__finish_transaction(svn_sqlit help diagnosing the original error and help in finding where a reset statement is missing. */ - err2 = reset_all_statements(db, err2); + err2 = svn_error_trace(reset_all_statements(db, err2)); err2 = svn_error_compose_create( - svn_sqlite__step_done(stmt), + svn_error_trace(svn_sqlite__step_done(stmt)), err2); + } - return svn_error_compose_create(err, - err2); + return svn_error_compose_create(err, err2); } SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_COMMIT_TRANSACTION)); @@ -1358,7 +1358,7 @@ svn_sqlite__finish_savepoint(svn_sqlite_ STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN); if (!err2) - err2 = svn_sqlite__step_done(stmt); + err2 = svn_error_trace(svn_sqlite__step_done(stmt)); if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY) { @@ -1368,8 +1368,10 @@ svn_sqlite__finish_savepoint(svn_sqlite_ ### See huge comment in svn_sqlite__finish_transaction for further details */ - err2 = reset_all_statements(db, err2); - err2 = svn_error_compose_create(svn_sqlite__step_done(stmt), err2); + err2 = svn_error_trace(reset_all_statements(db, err2)); + err2 = svn_error_compose_create( + svn_error_trace(svn_sqlite__step_done(stmt)), + err2); } err = svn_error_compose_create(err, err2); @@ -1377,9 +1379,9 @@ svn_sqlite__finish_savepoint(svn_sqlite_ STMT_INTERNAL_RELEASE_SAVEPOINT_SVN); if (!err2) - err2 = svn_sqlite__step_done(stmt); + err2 = svn_error_trace(svn_sqlite__step_done(stmt)); - return svn_error_trace(svn_error_compose_create(err, err2)); + return svn_error_compose_create(err, err2); } SVN_ERR(get_internal_statement(&stmt, db, Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/string.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/string.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/string.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/string.c Wed Mar 4 15:56:18 2015 @@ -1300,7 +1300,7 @@ svn__base36toui64(const char **next, con } -unsigned int +apr_size_t svn_cstring__similarity(const char *stra, const char *strb, svn_membuf_t *buffer, apr_size_t *rlcs) { @@ -1312,7 +1312,7 @@ svn_cstring__similarity(const char *stra return svn_string__similarity(&stringa, &stringb, buffer, rlcs); } -unsigned int +apr_size_t svn_string__similarity(const svn_string_t *stringa, const svn_string_t *stringb, svn_membuf_t *buffer, apr_size_t *rlcs) @@ -1401,9 +1401,9 @@ svn_string__similarity(const svn_string_ /* Return similarity ratio rounded to 4 significant digits */ if (total) - return(unsigned int)((2000 * lcs + total/2) / total); + return ((2 * SVN_STRING__SIM_RANGE_MAX * lcs + total/2) / total); else - return 1000; + return SVN_STRING__SIM_RANGE_MAX; } apr_size_t Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/utf8proc/utf8proc.h URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/utf8proc/utf8proc.h?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/utf8proc/utf8proc.h (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/utf8proc/utf8proc.h Wed Mar 4 15:56:18 2015 @@ -71,18 +71,26 @@ #include <stdlib.h> #include <sys/types.h> #ifdef _MSC_VER -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -#ifdef _WIN64 -#define ssize_t __int64 -#else -#define ssize_t int -#endif -typedef unsigned char bool; -enum {false, true}; +# if _MSC_VER >= 1600 +# include <stdint.h> +# else + typedef signed char int8_t; + typedef unsigned char uint8_t; + typedef short int16_t; + typedef unsigned short uint16_t; + typedef int int32_t; +# endif +# if _MSC_VER >= 1800 +# include <stdbool.h> +# else + typedef unsigned char bool; + enum {false, true}; +# endif +# ifdef _WIN64 +# define ssize_t __int64 +# else +# define ssize_t int +# endif #elif defined(HAVE_STDBOOL_H) && defined(HAVE_INTTYPES_H) #include <stdbool.h> #include <inttypes.h> Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/win32_crashrpt.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/win32_crashrpt.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/win32_crashrpt.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/win32_crashrpt.c Wed Mar 4 15:56:18 2015 @@ -422,7 +422,7 @@ write_var_values(PSYMBOL_INFO sym_info, if (log_params && sym_info->Flags & SYMFLAG_PARAMETER) { if (last_nr_of_frame == nr_of_frame) - fprintf(log_file, ", ", 2); + fprintf(log_file, ", "); else last_nr_of_frame = nr_of_frame; Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c Wed Mar 4 15:56:18 2015 @@ -124,7 +124,7 @@ svn_x509_certinfo_dup(const svn_x509_cer typedef struct asn1_oid { const unsigned char *oid; - const ptrdiff_t oid_len; + const apr_size_t oid_len; const char *short_label; const char *long_label; } asn1_oid; Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/conflicts.c Wed Mar 4 15:56:18 2015 @@ -2338,7 +2338,7 @@ static svn_error_t * resolve_prop_conflict_on_node(svn_boolean_t *did_resolve, svn_wc__db_t *db, const char *local_abspath, - const svn_skel_t *conflicts, + svn_skel_t *conflicts, const char *conflicted_propname, svn_wc_conflict_choice_t conflict_choice, const char *merged_file, @@ -2357,6 +2357,8 @@ resolve_prop_conflict_on_node(svn_boolea svn_skel_t *work_items = NULL; svn_wc_operation_t operation; svn_boolean_t prop_conflicted; + apr_hash_t *actual_props; + svn_boolean_t resolved_all, resolved_all_prop; *did_resolve = FALSE; @@ -2372,12 +2374,35 @@ resolve_prop_conflict_on_node(svn_boolea db, local_abspath, conflicts, scratch_pool, scratch_pool)); + if (!conflicted_props) + { + /* We have a pre 1.8 property conflict. Just mark it resolved */ + + SVN_ERR(remove_artifact_file_if_exists(&work_items, did_resolve, + db, local_abspath, prop_reject_file, + scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, TRUE, FALSE, + work_items, scratch_pool)); + SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton, + scratch_pool)); + return SVN_NO_ERROR; + } + + if (conflicted_propname[0] != '\0' + && !svn_hash_gets(conflicted_props, conflicted_propname)) + { + return SVN_NO_ERROR; /* This property is not conflicted! */ + } + if (operation == svn_wc_operation_merge) SVN_ERR(svn_wc__db_read_pristine_props(&old_props, db, local_abspath, scratch_pool, scratch_pool)); else old_props = their_old_props; + SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath, + scratch_pool, scratch_pool)); + /* We currently handle *_conflict as *_full as this argument is currently always applied for all conflicts on a node at the same time. Giving an error would break some tests that assumed that this would just @@ -2405,11 +2430,7 @@ resolve_prop_conflict_on_node(svn_boolea case svn_wc_conflict_choose_merged: if ((merged_file || merged_value) && conflicted_propname[0] != '\0') { - apr_hash_t *actual_props; - - SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath, - scratch_pool, scratch_pool)); - resolve_from = actual_props; + resolve_from = apr_hash_copy(scratch_pool, actual_props); if (!merged_value) { @@ -2433,15 +2454,26 @@ resolve_prop_conflict_on_node(svn_boolea _("Invalid 'conflict_result' argument")); } - if (conflicted_props && apr_hash_count(conflicted_props) && resolve_from) + + if (resolve_from) { apr_hash_index_t *hi; - apr_hash_t *actual_props; + apr_hash_t *apply_on_props; - SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath, - scratch_pool, scratch_pool)); + if (conflicted_propname[0] == '\0') + { + /* Apply to all conflicted properties */ + apply_on_props = conflicted_props; + } + else + { + /* Apply to a single property */ + apply_on_props = apr_hash_make(scratch_pool); + svn_hash_sets(apply_on_props, conflicted_propname, ""); + } - for (hi = apr_hash_first(scratch_pool, conflicted_props); + /* Apply the selected changes */ + for (hi = apr_hash_first(scratch_pool, apply_on_props); hi; hi = apr_hash_next(hi)) { @@ -2452,28 +2484,67 @@ resolve_prop_conflict_on_node(svn_boolea svn_hash_sets(actual_props, propname, new_value); } - SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props, - FALSE, NULL, NULL, - scratch_pool)); } + /*else the user accepted the properties as-is */ - /* Legacy behavior: Only report property conflicts as resolved when the - property reject file exists + /* This function handles conflicted_propname "" as resolving + all property conflicts... Just what we need here */ + SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts, + db, local_abspath, + FALSE, conflicted_propname, + FALSE, + scratch_pool, scratch_pool)); - If not the UI shows the conflict as already resolved - (and in this case we just remove the in-db conflict) */ + if (!resolved_all) + { + /* Are there still property conflicts left? (or only...) */ + SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, NULL, &prop_conflicted, + NULL, db, local_abspath, conflicts, + scratch_pool, scratch_pool)); - { - svn_skel_t *work_item; + resolved_all_prop = (! prop_conflicted); + } + else + { + resolved_all_prop = TRUE; + conflicts = NULL; + } - SVN_ERR(remove_artifact_file_if_exists(&work_item, did_resolve, - db, local_abspath, prop_reject_file, - scratch_pool, scratch_pool)); - work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool); - } + if (resolved_all_prop) + { + /* Legacy behavior: Only report property conflicts as resolved when the + property reject file exists + + If not the UI shows the conflict as already resolved + (and in this case we just remove the in-db conflict) */ + SVN_ERR(remove_artifact_file_if_exists(&work_items, did_resolve, + db, local_abspath, + prop_reject_file, + scratch_pool, scratch_pool)); + } + else + { + /* Create a new prej file, based on the remaining conflicts */ + SVN_ERR(svn_wc__wq_build_prej_install(&work_items, + db, local_abspath, + scratch_pool, scratch_pool)); + *did_resolve = TRUE; /* We resolved a property conflict */ + } + + /* This installs the updated conflict skel */ + SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props, + FALSE, conflicts, work_items, + scratch_pool)); + + if (resolved_all) + { + /* Remove the whole conflict. Should probably be integrated + into the op_set_props() call */ + SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, + FALSE, TRUE, FALSE, + NULL, scratch_pool)); + } - SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, TRUE, FALSE, - work_items, scratch_pool)); SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton, scratch_pool)); @@ -2570,7 +2641,8 @@ resolve_tree_conflict_on_node(svn_boolea const char *dup_abspath; if (!resolve_later - || err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE) + || (err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE + && err->apr_err != SVN_ERR_WC_FOUND_CONFLICT)) return svn_error_trace(err); svn_error_clear(err); @@ -2651,7 +2723,8 @@ resolve_tree_conflict_on_node(svn_boolea const char *dup_abspath; if (!resolve_later - || err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE) + || (err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE + && err->apr_err != SVN_ERR_WC_FOUND_CONFLICT)) return svn_error_trace(err); svn_error_clear(err); @@ -3014,33 +3087,11 @@ svn_wc__resolve_conflicts(svn_wc_context void *notify_baton, apr_pool_t *scratch_pool) { - svn_node_kind_t kind; - svn_boolean_t conflicted; struct conflict_status_walker_baton cswb; apr_pool_t *iterpool = NULL; svn_error_t *err; - /* ### the underlying code does NOT support resolving individual - ### properties. bail out if the caller tries it. */ - if (resolve_prop != NULL && *resolve_prop != '\0') - return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL, - U_("Resolving a single property is not (yet) " - "supported.")); - - /* ### Just a versioned check? */ - /* Conflicted is set to allow invoking on actual only nodes */ - SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, &conflicted, - NULL, NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - - /* When the implementation still used the entry walker, depth - unknown was translated to infinity. */ - if (kind != svn_node_dir) - depth = svn_depth_empty; - else if (depth == svn_depth_unknown) + if (depth == svn_depth_unknown) depth = svn_depth_infinity; cswb.db = wc_ctx->db; Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/entries.c Wed Mar 4 15:56:18 2015 @@ -45,11 +45,15 @@ #include "wc_db.h" #include "wc-queries.h" /* for STMT_* */ +#define SVN_WC__I_AM_WC_DB + #include "svn_private_config.h" #include "private/svn_wc_private.h" #include "private/svn_sqlite.h" #include "token-map.h" +#include "wc_db_private.h" + #define MAYBE_ALLOC(x,p) ((x) ? (x) : apr_pcalloc((p), sizeof(*(x)))) @@ -214,6 +218,8 @@ get_info_for_deleted(svn_wc_entry_t *ent svn_wc__db_lock_t **lock, svn_wc__db_t *db, const char *entry_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *entry_relpath, const svn_wc_entry_t *parent_entry, svn_boolean_t have_base, svn_boolean_t have_more_work, @@ -222,12 +228,13 @@ get_info_for_deleted(svn_wc_entry_t *ent { if (have_base && !have_more_work) { + apr_int64_t repos_id; /* This is the delete of a BASE node */ - SVN_ERR(svn_wc__db_base_get_info(NULL, kind, + SVN_ERR(svn_wc__db_base_get_info_internal( + NULL, kind, &entry->revision, repos_relpath, - &entry->repos, - &entry->uuid, + &repos_id, &entry->cmt_rev, &entry->cmt_date, &entry->cmt_author, @@ -237,16 +244,18 @@ get_info_for_deleted(svn_wc_entry_t *ent lock, &entry->has_props, NULL, NULL, - db, - entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); } else { - const char *work_del_abspath; + const char *work_del_relpath; const char *parent_repos_relpath; - const char *parent_abspath; + const char *parent_relpath; + apr_int64_t repos_id; /* This is a deleted child of a copy/move-here, so we need to scan up the WORKING tree to find the root of @@ -266,30 +275,33 @@ get_info_for_deleted(svn_wc_entry_t *ent scratch_pool)); /* working_size and text_time unavailable */ - SVN_ERR(svn_wc__db_scan_deletion(NULL, + SVN_ERR(svn_wc__db_scan_deletion_internal( + NULL, NULL, - &work_del_abspath, NULL, - db, entry_abspath, + &work_del_relpath, NULL, + wcroot, entry_relpath, scratch_pool, scratch_pool)); - SVN_ERR_ASSERT(work_del_abspath != NULL); - parent_abspath = svn_dirent_dirname(work_del_abspath, scratch_pool); + SVN_ERR_ASSERT(work_del_relpath != NULL); + parent_relpath = svn_relpath_dirname(work_del_relpath, scratch_pool); /* The parent directory of the delete root must be added, so we can find the required information there */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, + SVN_ERR(svn_wc__db_scan_addition_internal( + NULL, NULL, &parent_repos_relpath, - &entry->repos, - &entry->uuid, - NULL, NULL, NULL, NULL, - db, parent_abspath, + &repos_id, + NULL, NULL, NULL, + wcroot, parent_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); /* Now glue it all together */ *repos_relpath = svn_relpath_join(parent_repos_relpath, - svn_dirent_is_child(parent_abspath, - entry_abspath, - NULL), + svn_relpath_skip_ancestor( + parent_relpath, + entry_relpath), result_pool); @@ -298,11 +310,12 @@ get_info_for_deleted(svn_wc_entry_t *ent if (have_base) { svn_wc__db_status_t status; - SVN_ERR(svn_wc__db_base_get_info(&status, NULL, &entry->revision, + SVN_ERR(svn_wc__db_base_get_info_internal( + &status, NULL, &entry->revision, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, lock, NULL, NULL, + NULL, NULL, lock, NULL, NULL, NULL, - db, entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); if (status == svn_wc__db_status_not_present) @@ -370,12 +383,17 @@ write_tree_conflicts(const char **confli If this node is "this dir", then PARENT_ENTRY should be NULL. Otherwise, it should refer to the entry for the child's parent directory. + ### All database read operations should really use wcroot, dir_relpath, + as that restores obstruction compatibility with <= 1.6.0 + but that has been the case since the introduction of WC-NG in 1.7.0 + Temporary allocations are made in SCRATCH_POOL. */ static svn_error_t * read_one_entry(const svn_wc_entry_t **new_entry, svn_wc__db_t *db, - apr_int64_t wc_id, const char *dir_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *dir_relpath, const char *name, const svn_wc_entry_t *parent_entry, apr_pool_t *result_pool, @@ -388,24 +406,28 @@ read_one_entry(const svn_wc_entry_t **ne const svn_checksum_t *checksum; svn_filesize_t translated_size; svn_wc_entry_t *entry = alloc_entry(result_pool); + const char *entry_relpath; const char *entry_abspath; + apr_int64_t repos_id; + apr_int64_t original_repos_id; const char *original_repos_relpath; const char *original_root_url; svn_boolean_t conflicted; svn_boolean_t have_base; svn_boolean_t have_more_work; + svn_boolean_t op_root; - entry->name = name; + entry->name = apr_pstrdup(result_pool, name); + entry_relpath = svn_relpath_join(dir_relpath, entry->name, scratch_pool); entry_abspath = svn_dirent_join(dir_abspath, entry->name, scratch_pool); - SVN_ERR(svn_wc__db_read_info( + SVN_ERR(svn_wc__db_read_info_internal( &status, &kind, &entry->revision, &repos_relpath, - &entry->repos, - &entry->uuid, + &repos_id, &entry->cmt_rev, &entry->cmt_date, &entry->cmt_author, @@ -413,24 +435,27 @@ read_one_entry(const svn_wc_entry_t **ne &checksum, NULL, &original_repos_relpath, - &original_root_url, - NULL, + &original_repos_id, &entry->copyfrom_rev, &lock, &translated_size, &entry->text_time, &entry->changelist, &conflicted, - NULL /* op_root */, + &op_root, &entry->has_props /* have_props */, &entry->has_prop_mods /* props_mod */, &have_base, &have_more_work, NULL /* have_work */, - db, - entry_abspath, - result_pool, - scratch_pool)); + wcroot, entry_relpath, + result_pool, scratch_pool)); + + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&original_root_url, NULL, + wcroot, original_repos_id, + result_pool)); if (entry->has_prop_mods) entry->has_props = TRUE; @@ -494,13 +519,15 @@ read_one_entry(const svn_wc_entry_t **ne /* Grab inherited repository information, if necessary. */ if (repos_relpath == NULL) { - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, &repos_relpath, - &entry->repos, - &entry->uuid, NULL, NULL, NULL, + SVN_ERR(svn_wc__db_base_get_info_internal( + NULL, NULL, NULL, &repos_relpath, + &repos_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - db, entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); } entry->incomplete = (status == svn_wc__db_status_incomplete); @@ -520,13 +547,14 @@ read_one_entry(const svn_wc_entry_t **ne entry->copied = FALSE; else { - const char *work_del_abspath; - SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, - &work_del_abspath, NULL, - db, entry_abspath, + const char *work_del_relpath; + SVN_ERR(svn_wc__db_scan_deletion_internal( + NULL, NULL, + &work_del_relpath, NULL, + wcroot, entry_relpath, scratch_pool, scratch_pool)); - if (work_del_abspath) + if (work_del_relpath) entry->copied = TRUE; } @@ -564,13 +592,14 @@ read_one_entry(const svn_wc_entry_t **ne /* ENTRY->REVISION is overloaded. When a node is schedule-add or -replace, then REVISION refers to the BASE node's revision that is being overwritten. We need to fetch it now. */ - SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, + SVN_ERR(svn_wc__db_base_get_info_internal( + &base_status, NULL, &entry->revision, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - db, entry_abspath, + NULL, NULL, NULL, + wcroot, entry_relpath, scratch_pool, scratch_pool)); @@ -604,18 +633,27 @@ read_one_entry(const svn_wc_entry_t **ne have important data. Set up stuff to kill that idea off, and finish up this entry. */ { - SVN_ERR(svn_wc__db_scan_addition(&work_status, - &op_root_abspath, + const char *op_root_relpath; + SVN_ERR(svn_wc__db_scan_addition_internal( + &work_status, + &op_root_relpath, &repos_relpath, - &entry->repos, - &entry->uuid, + &repos_id, &scanned_original_relpath, - NULL, NULL, /* original_root|uuid */ + NULL /* original_repos_id */, &original_revision, - db, - entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); + + if (!op_root_relpath) + op_root_abspath = NULL; + else + op_root_abspath = svn_dirent_join(wcroot->abspath, op_root_relpath, + scratch_pool); + /* In wc.db we want to keep the valid revision of the not-present BASE_REV, but when we used entries we set the revision to 0 when adding a new node over a not present base node. */ @@ -676,10 +714,12 @@ read_one_entry(const svn_wc_entry_t **ne mixed-revision situation. */ if (!is_copied_child) { - const char *parent_abspath; + const char *parent_relpath; svn_error_t *err; const char *parent_repos_relpath; const char *parent_root_url; + apr_int64_t parent_repos_id; + const char *op_root_relpath; /* When we insert entries into the database, we will construct additional copyfrom records for mixed-revision @@ -706,15 +746,16 @@ read_one_entry(const svn_wc_entry_t **ne Note that the parent could be added/copied/moved-here. There is no way for it to be deleted/moved-away and have *this* node appear as copied. */ - parent_abspath = svn_dirent_dirname(entry_abspath, - scratch_pool); - err = svn_wc__db_scan_addition(NULL, - &op_root_abspath, - NULL, NULL, NULL, - &parent_repos_relpath, - &parent_root_url, + parent_relpath = svn_relpath_dirname(entry_relpath, + scratch_pool); + err = svn_wc__db_scan_addition_internal( + NULL, + &op_root_relpath, NULL, NULL, - db, parent_abspath, + &parent_repos_relpath, + &parent_repos_id, + NULL, + wcroot, parent_relpath, scratch_pool, scratch_pool); if (err) @@ -722,10 +763,24 @@ read_one_entry(const svn_wc_entry_t **ne if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) return svn_error_trace(err); svn_error_clear(err); + op_root_abspath = NULL; + parent_repos_relpath = NULL; + parent_root_url = NULL; } - else if (parent_root_url != NULL + else + { + SVN_ERR(svn_wc__db_fetch_repos_info(&parent_root_url, NULL, + wcroot, parent_repos_id, + scratch_pool)); + op_root_abspath = svn_dirent_join(wcroot->abspath, + op_root_relpath, + scratch_pool); + } + + if (parent_root_url != NULL && strcmp(original_root_url, parent_root_url) == 0) { + const char *relpath_to_entry = svn_dirent_is_child( op_root_abspath, entry_abspath, NULL); const char *entry_repos_relpath = svn_relpath_join( @@ -828,6 +883,7 @@ read_one_entry(const svn_wc_entry_t **ne &checksum, &lock, db, entry_abspath, + wcroot, entry_relpath, parent_entry, have_base, have_more_work, result_pool, scratch_pool)); @@ -870,7 +926,7 @@ read_one_entry(const svn_wc_entry_t **ne /* We got a SHA-1, get the corresponding MD-5. */ if (checksum->kind != svn_checksum_md5) SVN_ERR(svn_wc__db_pristine_get_md5(&checksum, db, - entry_abspath, checksum, + dir_abspath, checksum, scratch_pool, scratch_pool)); SVN_ERR_ASSERT(checksum->kind == svn_checksum_md5); @@ -882,8 +938,9 @@ read_one_entry(const svn_wc_entry_t **ne svn_skel_t *conflict; svn_boolean_t text_conflicted; svn_boolean_t prop_conflicted; - SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, db, entry_abspath, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, + wcroot, entry_relpath, + scratch_pool, scratch_pool)); SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted, &prop_conflicted, NULL, @@ -956,7 +1013,9 @@ read_one_entry(const svn_wc_entry_t **ne static svn_error_t * read_entries_new(apr_hash_t **result_entries, svn_wc__db_t *db, - const char *local_abspath, + const char *dir_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *dir_relpath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { @@ -965,11 +1024,12 @@ read_entries_new(apr_hash_t **result_ent apr_pool_t *iterpool = svn_pool_create(scratch_pool); int i; const svn_wc_entry_t *parent_entry; - apr_int64_t wc_id = 1; /* ### hacky. should remove. */ entries = apr_hash_make(result_pool); - SVN_ERR(read_one_entry(&parent_entry, db, wc_id, local_abspath, + SVN_ERR(read_one_entry(&parent_entry, + db, dir_abspath, + wcroot, dir_relpath, "" /* name */, NULL /* parent_entry */, result_pool, iterpool)); @@ -978,8 +1038,8 @@ read_entries_new(apr_hash_t **result_ent /* Use result_pool so that the child names (used by reference, rather than copied) appear in result_pool. */ SVN_ERR(svn_wc__db_read_children(&children, db, - local_abspath, - result_pool, iterpool)); + dir_abspath, + scratch_pool, iterpool)); for (i = children->nelts; i--; ) { const char *name = APR_ARRAY_IDX(children, i, const char *); @@ -988,7 +1048,9 @@ read_entries_new(apr_hash_t **result_ent svn_pool_clear(iterpool); SVN_ERR(read_one_entry(&entry, - db, wc_id, local_abspath, name, parent_entry, + db, dir_abspath, + wcroot, dir_relpath, + name, parent_entry, result_pool, iterpool)); svn_hash_sets(entries, entry->name, entry); } @@ -1001,28 +1063,20 @@ read_entries_new(apr_hash_t **result_ent } -/* Read a pair of entries from wc_db in the directory DIR_ABSPATH. Return - the directory's entry in *PARENT_ENTRY and NAME's entry in *ENTRY. The - two returned pointers will be the same if NAME=="" ("this dir"). - - The parent entry must exist. - - The requested entry MAY exist. If it does not, then NULL will be returned. - - The resulting entries are allocated in RESULT_POOL, and all temporary - allocations are made in SCRATCH_POOL. */ static svn_error_t * -read_entry_pair(const svn_wc_entry_t **parent_entry, - const svn_wc_entry_t **entry, - svn_wc__db_t *db, - const char *dir_abspath, - const char *name, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +read_entry_pair_txn(const svn_wc_entry_t **parent_entry, + const svn_wc_entry_t **entry, + svn_wc__db_t *db, + const char *dir_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *dir_relpath, + const char *name, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - apr_int64_t wc_id = 1; /* ### hacky. should remove. */ - - SVN_ERR(read_one_entry(parent_entry, db, wc_id, dir_abspath, + SVN_ERR(read_one_entry(parent_entry, + db, dir_abspath, + wcroot, dir_relpath, "" /* name */, NULL /* parent_entry */, result_pool, scratch_pool)); @@ -1074,7 +1128,9 @@ read_entry_pair(const svn_wc_entry_t **p svn_error_t *err; err = read_one_entry(entry, - db, wc_id, dir_abspath, name, *parent_entry, + db, dir_abspath, + wcroot, dir_relpath, + name, *parent_entry, result_pool, scratch_pool); if (err) { @@ -1097,28 +1153,76 @@ read_entry_pair(const svn_wc_entry_t **p return SVN_NO_ERROR; } +/* Read a pair of entries from wc_db in the directory DIR_ABSPATH. Return + the directory's entry in *PARENT_ENTRY and NAME's entry in *ENTRY. The + two returned pointers will be the same if NAME=="" ("this dir"). + + The parent entry must exist. + + The requested entry MAY exist. If it does not, then NULL will be returned. + + The resulting entries are allocated in RESULT_POOL, and all temporary + allocations are made in SCRATCH_POOL. */ +static svn_error_t * +read_entry_pair(const svn_wc_entry_t **parent_entry, + const svn_wc_entry_t **entry, + svn_wc__db_t *db, + const char *dir_abspath, + const char *name, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *dir_relpath; + + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, + db, dir_abspath, + scratch_pool, scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_WC__DB_WITH_TXN(read_entry_pair_txn(parent_entry, entry, + db, dir_abspath, + wcroot, dir_relpath, + name, + result_pool, scratch_pool), + wcroot); + + return SVN_NO_ERROR; +} /* */ static svn_error_t * read_entries(apr_hash_t **entries, svn_wc__db_t *db, - const char *wcroot_abspath, + const char *dir_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { + svn_wc__db_wcroot_t *wcroot; + const char *dir_relpath; int wc_format; - SVN_ERR(svn_wc__db_temp_get_format(&wc_format, db, wcroot_abspath, + SVN_ERR(svn_wc__db_temp_get_format(&wc_format, db, dir_abspath, scratch_pool)); if (wc_format < SVN_WC__WC_NG_VERSION) return svn_error_trace(svn_wc__read_entries_old(entries, - wcroot_abspath, + dir_abspath, result_pool, scratch_pool)); - return svn_error_trace(read_entries_new(entries, db, wcroot_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, + db, dir_abspath, + scratch_pool, scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_WC__DB_WITH_TXN(read_entries_new(entries, + db, dir_abspath, + wcroot, dir_relpath, + result_pool, scratch_pool), + wcroot); + + return SVN_NO_ERROR; } @@ -1373,25 +1477,6 @@ prune_deleted(apr_hash_t **entries_prune return SVN_NO_ERROR; } -struct entries_read_baton_t -{ - apr_hash_t **new_entries; - svn_wc__db_t *db; - const char *local_abspath; - apr_pool_t *result_pool; -}; - -static svn_error_t * -entries_read_txn(void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool) -{ - struct entries_read_baton_t *erb = baton; - - SVN_ERR(read_entries(erb->new_entries, erb->db, erb->local_abspath, - erb->result_pool, scratch_pool)); - - return NULL; -} - svn_error_t * svn_wc__entries_read_internal(apr_hash_t **entries, svn_wc_adm_access_t *adm_access, @@ -1406,21 +1491,9 @@ svn_wc__entries_read_internal(apr_hash_t svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); const char *local_abspath = svn_wc__adm_access_abspath(adm_access); apr_pool_t *result_pool = svn_wc__adm_access_pool_internal(adm_access); - svn_sqlite__db_t *sdb; - struct entries_read_baton_t erb; - - /* ### Use the borrow DB api to handle all calls in a single read - ### transaction. This api is used extensively in our test suite - ### via the entries-read application. */ - - SVN_ERR(svn_wc__db_temp_borrow_sdb(&sdb, db, local_abspath, pool)); - - erb.db = db; - erb.local_abspath = local_abspath; - erb.new_entries = &new_entries; - erb.result_pool = result_pool; - SVN_ERR(svn_sqlite__with_lock(sdb, entries_read_txn, &erb, pool)); + SVN_ERR(read_entries(&new_entries, db, local_abspath, + result_pool, pool)); svn_wc__adm_access_set_entries(adm_access, new_entries); } Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c?rev=1664059&r1=1664058&r2=1664059&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/externals.c Wed Mar 4 15:56:18 2015 @@ -1496,8 +1496,8 @@ svn_wc__external_remove(svn_wc_context_t else { SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath, - FALSE, FALSE, FALSE, - SVN_INVALID_REVNUM, + FALSE, TRUE, FALSE, + 0, NULL, NULL, scratch_pool)); SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton,
