You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2015/01/03 15:00:44 UTC
svn commit: r1649205 [22/30] - in /subversion/branches/authzperf: ./ build/
build/ac-macros/ notes/ subversion/bindings/ctypes-python/
subversion/bindings/cxxhl/
subversion/bindings/javahl/tests/org/apache/subversion/javahl/
subversion/bindings/swig/ s...
Modified: subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c Sat Jan 3 14:00:41 2015
@@ -115,9 +115,6 @@ struct edit_baton_t
/* Possibly diff repos against text-bases instead of working files. */
svn_boolean_t diff_pristine;
- /* Hash whose keys are const char * changelist names. */
- apr_hash_t *changelist_hash;
-
/* Cancel function/baton */
svn_cancel_func_t cancel_func;
void *cancel_baton;
@@ -239,11 +236,6 @@ struct file_baton_t
* calculating diffs. USE_TEXT_BASE defines whether to compare
* against working files or text-bases. REVERSE_ORDER defines which
* direction to perform the diff.
- *
- * CHANGELIST_FILTER is a list of const char * changelist names, used to
- * filter diff output responses to only those items in one of the
- * specified changelists, empty (or NULL altogether) if no changelist
- * filtering is requested.
*/
static svn_error_t *
make_edit_baton(struct edit_baton_t **edit_baton,
@@ -255,20 +247,14 @@ make_edit_baton(struct edit_baton_t **ed
svn_boolean_t ignore_ancestry,
svn_boolean_t use_text_base,
svn_boolean_t reverse_order,
- const apr_array_header_t *changelist_filter,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
{
- apr_hash_t *changelist_hash = NULL;
struct edit_baton_t *eb;
SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
- if (changelist_filter && changelist_filter->nelts)
- SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter,
- pool));
-
eb = apr_pcalloc(pool, sizeof(*eb));
eb->db = db;
eb->anchor_abspath = apr_pstrdup(pool, anchor_abspath);
@@ -278,7 +264,6 @@ make_edit_baton(struct edit_baton_t **ed
eb->ignore_ancestry = ignore_ancestry;
eb->local_before_remote = reverse_order;
eb->diff_pristine = use_text_base;
- eb->changelist_hash = changelist_hash;
eb->cancel_func = cancel_func;
eb->cancel_baton = cancel_baton;
eb->pool = pool;
@@ -392,7 +377,6 @@ svn_wc__diff_base_working_diff(svn_wc__d
const char *local_abspath,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *changelist_hash,
const svn_diff_tree_processor_t *processor,
void *processor_dir_baton,
svn_boolean_t diff_pristine,
@@ -419,12 +403,11 @@ svn_wc__diff_base_working_diff(svn_wc__d
apr_hash_t *base_props;
apr_hash_t *local_props;
apr_array_header_t *prop_changes;
- const char *changelist;
SVN_ERR(svn_wc__db_read_info(&status, NULL, &db_revision, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &working_checksum, NULL,
NULL, NULL, NULL, NULL, NULL, &recorded_size,
- &recorded_time, &changelist, NULL, NULL,
+ &recorded_time, NULL, NULL, NULL,
&had_props, &props_mod, NULL, NULL, NULL,
db, local_abspath, scratch_pool, scratch_pool));
checksum = working_checksum;
@@ -433,12 +416,6 @@ svn_wc__diff_base_working_diff(svn_wc__d
|| status == svn_wc__db_status_added
|| (status == svn_wc__db_status_deleted && diff_pristine));
- /* If the item is not a member of a specified changelist (and there are
- some specified changelists), skip it. */
- if (changelist_hash && !svn_hash_gets(changelist_hash, changelist))
- return SVN_NO_ERROR;
-
-
if (status != svn_wc__db_status_normal)
{
SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, &db_revision,
@@ -768,7 +745,6 @@ walk_local_nodes_diff(struct edit_baton_
SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
child_relpath,
eb->processor, dir_baton,
- eb->changelist_hash,
eb->diff_pristine,
eb->cancel_func,
eb->cancel_baton,
@@ -778,7 +754,6 @@ walk_local_nodes_diff(struct edit_baton_
child_relpath,
depth_below_here,
eb->processor, dir_baton,
- eb->changelist_hash,
eb->diff_pristine,
eb->cancel_func,
eb->cancel_baton,
@@ -814,7 +789,6 @@ walk_local_nodes_diff(struct edit_baton_
db, child_abspath,
child_relpath,
eb->revnum,
- eb->changelist_hash,
eb->processor, dir_baton,
eb->diff_pristine,
eb->cancel_func,
@@ -837,7 +811,6 @@ walk_local_nodes_diff(struct edit_baton_
SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
child_relpath,
eb->processor, dir_baton,
- eb->changelist_hash,
eb->diff_pristine,
eb->cancel_func,
eb->cancel_baton,
@@ -846,7 +819,6 @@ walk_local_nodes_diff(struct edit_baton_
SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
child_relpath, depth_below_here,
eb->processor, dir_baton,
- eb->changelist_hash,
eb->diff_pristine,
eb->cancel_func,
eb->cancel_baton,
@@ -858,13 +830,9 @@ walk_local_nodes_diff(struct edit_baton_
if (compared)
return SVN_NO_ERROR;
- /* Check for local property mods on this directory, if we haven't
- already reported them and we aren't changelist-filted.
- ### it should be noted that we do not currently allow directories
- ### to be part of changelists, so if a changelist is provided, the
- ### changelist check will always fail. */
+ /* Check for local property mods on this directory, if we haven't
+ already reported them. */
if (! skip
- && ! eb->changelist_hash
&& ! in_anchor_not_target
&& props_mod)
{
@@ -907,7 +875,6 @@ svn_wc__diff_local_only_file(svn_wc__db_
const char *relpath,
const svn_diff_tree_processor_t *processor,
void *processor_parent_baton,
- apr_hash_t *changelist_hash,
svn_boolean_t diff_pristine,
svn_cancel_func_t cancel_func,
void *cancel_baton,
@@ -920,7 +887,6 @@ svn_wc__diff_local_only_file(svn_wc__db_
const svn_checksum_t *checksum;
const char *original_repos_relpath;
svn_revnum_t original_revision;
- const char *changelist;
svn_boolean_t had_props;
svn_boolean_t props_mod;
apr_hash_t *pristine_props;
@@ -936,7 +902,7 @@ svn_wc__diff_local_only_file(svn_wc__db_
NULL, NULL, NULL, NULL, &checksum, NULL,
&original_repos_relpath, NULL, NULL,
&original_revision, NULL, NULL, NULL,
- &changelist, NULL, NULL, &had_props,
+ NULL, NULL, NULL, &had_props,
&props_mod, NULL, NULL, NULL,
db, local_abspath,
scratch_pool, scratch_pool));
@@ -947,10 +913,6 @@ svn_wc__diff_local_only_file(svn_wc__db_
|| (status == svn_wc__db_status_deleted && diff_pristine)));
- if (changelist && changelist_hash
- && !svn_hash_gets(changelist_hash, changelist))
- return SVN_NO_ERROR;
-
if (status == svn_wc__db_status_deleted)
{
assert(diff_pristine);
@@ -1053,7 +1015,6 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
svn_depth_t depth,
const svn_diff_tree_processor_t *processor,
void *processor_parent_baton,
- apr_hash_t *changelist_hash,
svn_boolean_t diff_pristine,
svn_cancel_func_t cancel_func,
void *cancel_baton,
@@ -1075,9 +1036,6 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
svn_boolean_t skip_children = FALSE;
svn_diff_source_t *right_src = svn_diff__source_create(SVN_INVALID_REVNUM,
scratch_pool);
- svn_depth_t depth_below_here = depth;
- apr_hash_t *nodes;
- apr_hash_t *conflicts;
SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1128,71 +1086,81 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
processor,
scratch_pool, iterpool));
- SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts, db, local_abspath,
- FALSE /* base_tree_only */,
- scratch_pool, iterpool));
-
- if (depth_below_here == svn_depth_immediates)
- depth_below_here = svn_depth_empty;
-
- children = svn_sort__hash(nodes, svn_sort_compare_items_lexically,
- scratch_pool);
-
- for (i = 0; i < children->nelts; i++)
+ if ((depth > svn_depth_empty || depth == svn_depth_unknown)
+ && ! skip_children)
{
- svn_sort__item_t *item = &APR_ARRAY_IDX(children, i, svn_sort__item_t);
- const char *name = item->key;
- struct svn_wc__db_info_t *info = item->value;
- const char *child_abspath;
- const char *child_relpath;
+ svn_depth_t depth_below_here = depth;
+ apr_hash_t *nodes;
+ apr_hash_t *conflicts;
+
+ if (depth_below_here == svn_depth_immediates)
+ depth_below_here = svn_depth_empty;
- svn_pool_clear(iterpool);
+ SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts,
+ db, local_abspath,
+ FALSE /* base_tree_only */,
+ scratch_pool, iterpool));
- if (cancel_func)
- SVN_ERR(cancel_func(cancel_baton));
- child_abspath = svn_dirent_join(local_abspath, name, iterpool);
+ children = svn_sort__hash(nodes, svn_sort_compare_items_lexically,
+ scratch_pool);
- if (NOT_PRESENT(info->status))
+ for (i = 0; i < children->nelts; i++)
{
- continue;
- }
+ svn_sort__item_t *item = &APR_ARRAY_IDX(children, i, svn_sort__item_t);
+ const char *name = item->key;
+ struct svn_wc__db_info_t *info = item->value;
+ const char *child_abspath;
+ const char *child_relpath;
- /* If comparing against WORKING, skip entries that are
- schedule-deleted - they don't really exist. */
- if (!diff_pristine && info->status == svn_wc__db_status_deleted)
- continue;
+ svn_pool_clear(iterpool);
- child_relpath = svn_relpath_join(relpath, name, iterpool);
+ if (cancel_func)
+ SVN_ERR(cancel_func(cancel_baton));
- switch (info->kind)
- {
- case svn_node_file:
- case svn_node_symlink:
- SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
- child_relpath,
- processor, pdb,
- changelist_hash,
- diff_pristine,
- cancel_func, cancel_baton,
- scratch_pool));
- break;
+ child_abspath = svn_dirent_join(local_abspath, name, iterpool);
- case svn_node_dir:
- if (depth > svn_depth_files || depth == svn_depth_unknown)
+ if (NOT_PRESENT(info->status))
{
- SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
- child_relpath, depth_below_here,
- processor, pdb,
- changelist_hash,
- diff_pristine,
- cancel_func, cancel_baton,
- iterpool));
+ continue;
}
- break;
- default:
- break;
+ /* If comparing against WORKING, skip entries that are
+ schedule-deleted - they don't really exist. */
+ if (!diff_pristine && info->status == svn_wc__db_status_deleted)
+ continue;
+
+ child_relpath = svn_relpath_join(relpath, name, iterpool);
+
+ switch (info->kind)
+ {
+ case svn_node_file:
+ case svn_node_symlink:
+ SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
+ child_relpath,
+ processor, pdb,
+ diff_pristine,
+ cancel_func, cancel_baton,
+ scratch_pool));
+ break;
+
+ case svn_node_dir:
+ if (depth > svn_depth_files || depth == svn_depth_unknown)
+ {
+ SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
+ child_relpath,
+ depth_below_here,
+ processor, pdb,
+ diff_pristine,
+ cancel_func,
+ cancel_baton,
+ iterpool));
+ }
+ break;
+
+ default:
+ break;
+ }
}
}
@@ -1282,7 +1250,6 @@ handle_local_only(struct dir_baton_t *pb
svn_relpath_join(pb->relpath, name, scratch_pool),
repos_delete ? svn_depth_infinity : depth,
eb->processor, pb->pdb,
- eb->changelist_hash,
eb->diff_pristine,
eb->cancel_func, eb->cancel_baton,
scratch_pool));
@@ -1293,7 +1260,6 @@ handle_local_only(struct dir_baton_t *pb
svn_dirent_join(pb->local_abspath, name, scratch_pool),
svn_relpath_join(pb->relpath, name, scratch_pool),
eb->processor, pb->pdb,
- eb->changelist_hash,
eb->diff_pristine,
eb->cancel_func, eb->cancel_baton,
scratch_pool));
@@ -2068,7 +2034,14 @@ close_file(void *file_baton,
const char *repos_file;
apr_hash_t *repos_props;
- if (!fb->skip && expected_md5_digest != NULL)
+ if (fb->skip)
+ {
+ svn_pool_destroy(fb->pool); /* destroys scratch_pool and fb */
+ SVN_ERR(maybe_done(pb));
+ return SVN_NO_ERROR;
+ }
+
+ if (expected_md5_digest != NULL)
{
svn_checksum_t *expected_checksum;
const svn_checksum_t *result_checksum;
@@ -2123,11 +2096,7 @@ close_file(void *file_baton,
}
}
- if (fb->skip)
- {
- /* Diff processor requested skipping information */
- }
- else if (fb->repos_only)
+ if (fb->repos_only)
{
SVN_ERR(eb->processor->file_deleted(fb->relpath,
fb->left_src,
@@ -2307,12 +2276,24 @@ svn_wc__get_diff_editor(const svn_delta_
SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
+ /* Apply changelist filtering to the output */
+ if (changelist_filter && changelist_filter->nelts)
+ {
+ apr_hash_t *changelist_hash;
+
+ SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter,
+ result_pool));
+ diff_processor = svn_wc__changelist_filter_tree_processor_create(
+ diff_processor, wc_ctx, anchor_abspath,
+ changelist_hash, result_pool);
+ }
+
SVN_ERR(make_edit_baton(&eb,
wc_ctx->db,
anchor_abspath, target,
diff_processor,
depth, ignore_ancestry,
- use_text_base, reverse_order, changelist_filter,
+ use_text_base, reverse_order,
cancel_func, cancel_baton,
result_pool));
@@ -2778,3 +2759,329 @@ svn_wc__wrap_diff_callbacks(const svn_di
*diff_processor = processor;
return SVN_NO_ERROR;
}
+
+/* =====================================================================
+ * A tree processor filter that filters by changelist membership
+ * =====================================================================
+ *
+ * The current implementation queries the WC for the changelist of each
+ * file as it comes through, and sets the 'skip' flag for a non-matching
+ * file.
+ *
+ * (It doesn't set the 'skip' flag for a directory, as we need to receive
+ * the changed/added/deleted/closed call to know when it is closed, in
+ * order to preserve the strict open-close semantics for the wrapped tree
+ * processor.)
+ *
+ * It passes on the opening and closing of every directory, even if there
+ * are no file changes to be passed on inside that directory.
+ */
+
+typedef struct filter_tree_baton_t
+{
+ const svn_diff_tree_processor_t *processor;
+ svn_wc_context_t *wc_ctx;
+ /* WC path of the root of the diff (where relpath = "") */
+ const char *root_local_abspath;
+ /* Hash whose keys are const char * changelist names. */
+ apr_hash_t *changelist_hash;
+} filter_tree_baton_t;
+
+static svn_error_t *
+filter_dir_opened(void **new_dir_baton,
+ svn_boolean_t *skip,
+ svn_boolean_t *skip_children,
+ const char *relpath,
+ const svn_diff_source_t *left_source,
+ const svn_diff_source_t *right_source,
+ const svn_diff_source_t *copyfrom_source,
+ void *parent_dir_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->dir_opened(new_dir_baton, skip, skip_children,
+ relpath,
+ left_source, right_source,
+ copyfrom_source,
+ parent_dir_baton,
+ fb->processor,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_added(const char *relpath,
+ const svn_diff_source_t *copyfrom_source,
+ const svn_diff_source_t *right_source,
+ /*const*/ apr_hash_t *copyfrom_props,
+ /*const*/ apr_hash_t *right_props,
+ void *dir_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->dir_closed(relpath,
+ NULL,
+ right_source,
+ dir_baton,
+ fb->processor,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_deleted(const char *relpath,
+ const svn_diff_source_t *left_source,
+ /*const*/ apr_hash_t *left_props,
+ void *dir_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->dir_closed(relpath,
+ left_source,
+ NULL,
+ dir_baton,
+ fb->processor,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_changed(const char *relpath,
+ const svn_diff_source_t *left_source,
+ const svn_diff_source_t *right_source,
+ /*const*/ apr_hash_t *left_props,
+ /*const*/ apr_hash_t *right_props,
+ const apr_array_header_t *prop_changes,
+ void *dir_baton,
+ const struct svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->dir_closed(relpath,
+ left_source,
+ right_source,
+ dir_baton,
+ fb->processor,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_closed(const char *relpath,
+ const svn_diff_source_t *left_source,
+ const svn_diff_source_t *right_source,
+ void *dir_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->dir_closed(relpath,
+ left_source,
+ right_source,
+ dir_baton,
+ fb->processor,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_opened(void **new_file_baton,
+ svn_boolean_t *skip,
+ const char *relpath,
+ const svn_diff_source_t *left_source,
+ const svn_diff_source_t *right_source,
+ const svn_diff_source_t *copyfrom_source,
+ void *dir_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+ const char *local_abspath
+ = svn_dirent_join(fb->root_local_abspath, relpath, scratch_pool);
+
+ /* Skip if not a member of a given changelist */
+ if (! svn_wc__changelist_match(fb->wc_ctx, local_abspath,
+ fb->changelist_hash, scratch_pool))
+ {
+ *skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(fb->processor->file_opened(new_file_baton,
+ skip,
+ relpath,
+ left_source,
+ right_source,
+ copyfrom_source,
+ dir_baton,
+ fb->processor,
+ result_pool,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_added(const char *relpath,
+ const svn_diff_source_t *copyfrom_source,
+ const svn_diff_source_t *right_source,
+ const char *copyfrom_file,
+ const char *right_file,
+ /*const*/ apr_hash_t *copyfrom_props,
+ /*const*/ apr_hash_t *right_props,
+ void *file_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->file_added(relpath,
+ copyfrom_source,
+ right_source,
+ copyfrom_file,
+ right_file,
+ copyfrom_props,
+ right_props,
+ file_baton,
+ fb->processor,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_deleted(const char *relpath,
+ const svn_diff_source_t *left_source,
+ const char *left_file,
+ /*const*/ apr_hash_t *left_props,
+ void *file_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->file_deleted(relpath,
+ left_source,
+ left_file,
+ left_props,
+ file_baton,
+ fb->processor,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_changed(const char *relpath,
+ const svn_diff_source_t *left_source,
+ const svn_diff_source_t *right_source,
+ const char *left_file,
+ const char *right_file,
+ /*const*/ apr_hash_t *left_props,
+ /*const*/ apr_hash_t *right_props,
+ svn_boolean_t file_modified,
+ const apr_array_header_t *prop_changes,
+ void *file_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->file_changed(relpath,
+ left_source,
+ right_source,
+ left_file,
+ right_file,
+ left_props,
+ right_props,
+ file_modified,
+ prop_changes,
+ file_baton,
+ fb->processor,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_closed(const char *relpath,
+ const svn_diff_source_t *left_source,
+ const svn_diff_source_t *right_source,
+ void *file_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->file_closed(relpath,
+ left_source,
+ right_source,
+ file_baton,
+ fb->processor,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_node_absent(const char *relpath,
+ void *dir_baton,
+ const svn_diff_tree_processor_t *processor,
+ apr_pool_t *scratch_pool)
+{
+ struct filter_tree_baton_t *fb = processor->baton;
+
+ SVN_ERR(fb->processor->node_absent(relpath,
+ dir_baton,
+ fb->processor,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+const svn_diff_tree_processor_t *
+svn_wc__changelist_filter_tree_processor_create(
+ const svn_diff_tree_processor_t *processor,
+ svn_wc_context_t *wc_ctx,
+ const char *root_local_abspath,
+ apr_hash_t *changelist_hash,
+ apr_pool_t *result_pool)
+{
+ struct filter_tree_baton_t *fb;
+ svn_diff_tree_processor_t *filter;
+
+ if (! changelist_hash)
+ return processor;
+
+ fb = apr_pcalloc(result_pool, sizeof(*fb));
+ fb->processor = processor;
+ fb->wc_ctx = wc_ctx;
+ fb->root_local_abspath = root_local_abspath;
+ fb->changelist_hash = changelist_hash;
+
+ filter = svn_diff__tree_processor_create(fb, result_pool);
+ filter->dir_opened = filter_dir_opened;
+ filter->dir_added = filter_dir_added;
+ filter->dir_deleted = filter_dir_deleted;
+ filter->dir_changed = filter_dir_changed;
+ filter->dir_closed = filter_dir_closed;
+
+ filter->file_opened = filter_file_opened;
+ filter->file_added = filter_file_added;
+ filter->file_deleted = filter_file_deleted;
+ filter->file_changed = filter_file_changed;
+ filter->file_closed = filter_file_closed;
+
+ filter->node_absent = filter_node_absent;
+
+ return filter;
+}
+
Modified: subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c Sat Jan 3 14:00:41 2015
@@ -89,9 +89,6 @@ struct diff_baton
/* Should this diff ignore node ancestry? */
svn_boolean_t ignore_ancestry;
- /* Hash whose keys are const char * changelist names. */
- apr_hash_t *changelist_hash;
-
/* Cancel function/baton */
svn_cancel_func_t cancel_func;
void *cancel_baton;
@@ -249,11 +246,6 @@ diff_status_callback(void *baton,
if (eb->cur && eb->cur->skip_children)
return SVN_NO_ERROR;
- if (eb->changelist_hash != NULL
- && (!status->changelist
- || ! svn_hash_gets(eb->changelist_hash, status->changelist)))
- return SVN_NO_ERROR; /* Filtered via changelist */
-
/* This code does about the same thing as the inner body of
walk_local_nodes_diff() in diff_editor.c, except that
it is already filtered by the status walker, doesn't have to
@@ -358,7 +350,6 @@ diff_status_callback(void *baton,
SVN_ERR(svn_wc__diff_base_working_diff(db, child_abspath,
child_relpath,
SVN_INVALID_REVNUM,
- eb->changelist_hash,
eb->processor,
eb->cur
? eb->cur->baton
@@ -402,7 +393,6 @@ diff_status_callback(void *baton,
child_relpath,
eb->processor,
eb->cur ? eb->cur->baton : NULL,
- eb->changelist_hash,
FALSE,
eb->cancel_func,
eb->cancel_baton,
@@ -412,7 +402,6 @@ diff_status_callback(void *baton,
child_relpath, depth_below_here,
eb->processor,
eb->cur ? eb->cur->baton : NULL,
- eb->changelist_hash,
FALSE,
eb->cancel_func,
eb->cancel_baton,
@@ -475,15 +464,23 @@ svn_wc__diff7(const char **root_relpath,
if (root_is_dir)
*root_is_dir = (kind == svn_node_dir);
+ /* Apply changelist filtering to the output */
+ if (changelist_filter && changelist_filter->nelts)
+ {
+ apr_hash_t *changelist_hash;
+
+ SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter,
+ result_pool));
+ diff_processor = svn_wc__changelist_filter_tree_processor_create(
+ diff_processor, wc_ctx, local_abspath,
+ changelist_hash, result_pool);
+ }
+
eb.db = wc_ctx->db;
eb.processor = diff_processor;
eb.ignore_ancestry = ignore_ancestry;
eb.pool = scratch_pool;
- if (changelist_filter && changelist_filter->nelts)
- SVN_ERR(svn_hash_from_cstring_keys(&eb.changelist_hash, changelist_filter,
- scratch_pool));
-
if (ignore_ancestry)
get_all = TRUE; /* We need unmodified descendants of copies */
else
Modified: subversion/branches/authzperf/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/externals.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/externals.c Sat Jan 3 14:00:41 2015
@@ -159,7 +159,7 @@ find_and_remove_externals_revision(int *
svn_error_t *
svn_wc_parse_externals_description3(apr_array_header_t **externals_p,
- const char *parent_directory,
+ const char *defining_directory,
const char *desc,
svn_boolean_t canonicalize_url,
apr_pool_t *pool)
@@ -167,8 +167,8 @@ svn_wc_parse_externals_description3(apr_
int i;
apr_array_header_t *externals = NULL;
apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
- const char *parent_directory_display = svn_path_is_url(parent_directory) ?
- parent_directory : svn_dirent_local_style(parent_directory, pool);
+ const char *defining_directory_display = svn_path_is_url(defining_directory) ?
+ defining_directory : svn_dirent_local_style(defining_directory, pool);
/* If an error occurs halfway through parsing, *externals_p should stay
* untouched. So, store the list in a local var first. */
@@ -231,7 +231,7 @@ svn_wc_parse_externals_description3(apr_
(SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
_("Error parsing %s property on '%s': '%s'"),
SVN_PROP_EXTERNALS,
- parent_directory_display,
+ defining_directory_display,
line);
/* To make it easy to check for the forms, find and remove -r N
@@ -242,7 +242,7 @@ svn_wc_parse_externals_description3(apr_
SVN_ERR(find_and_remove_externals_revision(&rev_idx,
(const char **)line_parts,
num_line_parts, item,
- parent_directory_display,
+ defining_directory_display,
line, pool));
token0 = line_parts[0];
@@ -258,7 +258,7 @@ svn_wc_parse_externals_description3(apr_
"cannot use two absolute URLs ('%s' and '%s') in an external; "
"one must be a path where an absolute or relative URL is "
"checked out to"),
- SVN_PROP_EXTERNALS, parent_directory_display, token0, token1);
+ SVN_PROP_EXTERNALS, defining_directory_display, token0, token1);
if (0 == rev_idx && token1_is_url)
return svn_error_createf
@@ -266,7 +266,7 @@ svn_wc_parse_externals_description3(apr_
_("Invalid %s property on '%s': "
"cannot use a URL '%s' as the target directory for an external "
"definition"),
- SVN_PROP_EXTERNALS, parent_directory_display, token1);
+ SVN_PROP_EXTERNALS, defining_directory_display, token1);
if (1 == rev_idx && token0_is_url)
return svn_error_createf
@@ -274,7 +274,7 @@ svn_wc_parse_externals_description3(apr_
_("Invalid %s property on '%s': "
"cannot use a URL '%s' as the target directory for an external "
"definition"),
- SVN_PROP_EXTERNALS, parent_directory_display, token0);
+ SVN_PROP_EXTERNALS, defining_directory_display, token0);
/* The appearance of -r N or -rN forces the type of external.
If -r is at the beginning of the line or the first token is
@@ -316,7 +316,7 @@ svn_wc_parse_externals_description3(apr_
_("Invalid %s property on '%s': "
"target '%s' is an absolute path or involves '..'"),
SVN_PROP_EXTERNALS,
- parent_directory_display,
+ defining_directory_display,
item->target_dir);
if (canonicalize_url)
@@ -943,29 +943,62 @@ close_edit(void *edit_baton,
{
struct edit_baton *eb = edit_baton;
- if (!eb->file_closed
- || eb->iprops)
+ if (!eb->file_closed)
{
- apr_hash_t *wcroot_iprops = NULL;
+ /* The file wasn't updated, but its url or revision might have...
+ e.g. switch between branches for relative externals.
- if (eb->iprops)
- {
- wcroot_iprops = apr_hash_make(pool);
- svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops);
- }
+ Just bump the information as that is just as expensive as
+ investigating when we should and shouldn't update it...
+ and avoid hard to debug edge cases */
+
+ svn_node_kind_t kind;
+ const char *old_repos_relpath;
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
+ const svn_checksum_t *checksum;
+ apr_hash_t *pristine_props;
+ const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
+ eb->url, pool);
+
+ SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath,
+ NULL, NULL, &changed_rev, &changed_date,
+ &changed_author, NULL, &checksum, NULL,
+ NULL, NULL, &pristine_props, NULL,
+ eb->db, eb->local_abspath,
+ pool, pool));
- /* The node wasn't updated, so we just have to bump its revision */
- SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
- eb->local_abspath,
- svn_depth_infinity,
- NULL, NULL, NULL,
- *eb->target_revision,
- apr_hash_make(pool),
- wcroot_iprops,
- TRUE /* empty update */,
- eb->notify_func,
- eb->notify_baton,
- pool));
+ if (kind != svn_node_file)
+ return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+ _("Node '%s' is no existing file external"),
+ svn_dirent_local_style(eb->local_abspath,
+ pool));
+
+ SVN_ERR(svn_wc__db_external_add_file(
+ eb->db,
+ eb->local_abspath,
+ eb->wri_abspath,
+ repos_relpath,
+ eb->repos_root_url,
+ eb->repos_uuid,
+ *eb->target_revision,
+ pristine_props,
+ eb->iprops,
+ eb->changed_rev,
+ eb->changed_date,
+ eb->changed_author,
+ checksum,
+ NULL /* clear dav props */,
+ eb->record_ancestor_abspath,
+ eb->recorded_repos_relpath,
+ eb->recorded_peg_revision,
+ eb->recorded_revision,
+ FALSE, NULL,
+ TRUE /* keep_recorded_info */,
+ NULL /* conflict_skel */,
+ NULL /* work_items */,
+ pool));
}
return SVN_NO_ERROR;
Modified: subversion/branches/authzperf/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/node.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/node.c Sat Jan 3 14:00:41 2015
@@ -471,6 +471,7 @@ svn_wc__internal_walk_children(svn_wc__d
svn_node_kind_t kind;
svn_wc__db_status_t status;
apr_hash_t *changelist_hash = NULL;
+ const char *changelist = NULL;
SVN_ERR_ASSERT(walk_depth >= svn_depth_empty
&& walk_depth <= svn_depth_infinity);
@@ -483,14 +484,17 @@ svn_wc__internal_walk_children(svn_wc__d
SVN_ERR(svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ changelist_hash ? &changelist : NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
db, local_abspath, scratch_pool, scratch_pool));
SVN_ERR(convert_db_kind_to_node_kind(&kind, db_kind, status, show_hidden));
- if (svn_wc__internal_changelist_match(db, local_abspath,
- changelist_hash, scratch_pool))
- SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool));
+ if (!changelist_hash
+ || (changelist && svn_hash_gets(changelist_hash, changelist)))
+ {
+ SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool));
+ }
if (db_kind == svn_node_file
|| status == svn_wc__db_status_not_present
@@ -632,7 +636,6 @@ svn_wc__node_get_base(svn_node_kind_t *k
svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_boolean_t ignore_enoent,
- svn_boolean_t show_hidden,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -652,9 +655,8 @@ svn_wc__node_get_base(svn_node_kind_t *k
if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
return svn_error_trace(err);
else if (err
- || (!err && !show_hidden
- && (status != svn_wc__db_status_normal
- && status != svn_wc__db_status_incomplete)))
+ || (status != svn_wc__db_status_normal
+ && status != svn_wc__db_status_incomplete))
{
if (!ignore_enoent)
{
Modified: subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c Sat Jan 3 14:00:41 2015
@@ -4342,7 +4342,7 @@ close_file(void *file_baton,
|| strcmp(fb->new_repos_relpath, fb->old_repos_relpath) == 0)
{
SVN_ERR_ASSERT(prop->value == NULL);
- SVN_ERR(svn_wc__db_lock_remove(eb->db, fb->local_abspath,
+ SVN_ERR(svn_wc__db_lock_remove(eb->db, fb->local_abspath, NULL,
scratch_pool));
lock_state = svn_wc_notify_lock_state_unlocked;
Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc.h?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc.h Sat Jan 3 14:00:41 2015
@@ -249,52 +249,6 @@ svn_wc__context_create_with_db(svn_wc_co
apr_pool_t *
svn_wc__get_committed_queue_pool(const struct svn_wc_committed_queue_t *queue);
-
-/** Internal helper for svn_wc_process_committed_queue2().
- *
- * ### If @a queue is NULL, then ...?
- * ### else:
- * Bump an item from @a queue (the one associated with @a
- * local_abspath) to @a new_revnum after a commit succeeds, recursing
- * if @a recurse is set.
- *
- * @a new_date is the (server-side) date of the new revision, or 0.
- *
- * @a rev_author is the (server-side) author of the new
- * revision; it may be @c NULL.
- *
- * @a new_dav_cache is a hash of dav property changes to be made to
- * the @a local_abspath.
- * ### [JAF] Is it? See svn_wc_queue_committed3(). It ends up being
- * ### assigned as a whole to wc.db:BASE_NODE:dav_cache.
- *
- * If @a no_unlock is set, don't release any user locks on @a
- * local_abspath; otherwise release them as part of this processing.
- *
- * If @a keep_changelist is set, don't remove any changeset assignments
- * from @a local_abspath; otherwise, clear it of such assignments.
- *
- * If @a sha1_checksum is non-NULL, use it to identify the node's pristine
- * text.
- *
- * Set TOP_OF_RECURSE to TRUE to show that this the top of a possibly
- * recursive commit operation.
- */
-svn_error_t *
-svn_wc__process_committed_internal(svn_wc__db_t *db,
- const char *local_abspath,
- svn_boolean_t recurse,
- svn_boolean_t top_of_recurse,
- svn_revnum_t new_revnum,
- apr_time_t new_date,
- const char *rev_author,
- apr_hash_t *new_dav_cache,
- svn_boolean_t no_unlock,
- svn_boolean_t keep_changelist,
- const svn_checksum_t *sha1_checksum,
- const svn_wc_committed_queue_t *queue,
- apr_pool_t *scratch_pool);
-
/*** Update traversals. ***/
Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c Sat Jan 3 14:00:41 2015
@@ -4700,25 +4700,23 @@ struct op_copy_baton
const char *dst_op_root_relpath;
};
-/* Helper for svn_wc__db_op_copy().
- *
- * Implements svn_sqlite__transaction_callback_t. */
+/* Helper for svn_wc__db_op_copy(). */
static svn_error_t *
-op_copy_txn(void * baton,
- svn_sqlite__db_t *sdb,
+op_copy_txn(svn_wc__db_wcroot_t *wcroot,
+ struct op_copy_baton *ocb,
apr_pool_t *scratch_pool)
{
- struct op_copy_baton *ocb = baton;
int move_op_depth;
- if (sdb != ocb->dst_wcroot->sdb)
+ if (wcroot != ocb->dst_wcroot)
{
/* Source and destination databases differ; so also start a lock
- in the destination database, by calling ourself in a lock. */
+ in the destination database, by calling ourself in an extra lock. */
- return svn_error_trace(
- svn_sqlite__with_lock(ocb->dst_wcroot->sdb,
- op_copy_txn, ocb, scratch_pool));
+ SVN_WC__DB_WITH_TXN(op_copy_txn(ocb->dst_wcroot, ocb, scratch_pool),
+ ocb->dst_wcroot);
+
+ return SVN_NO_ERROR;
}
/* From this point we can assume a lock in the src and dst databases */
@@ -4769,8 +4767,8 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
/* Call with the sdb in src_wcroot. It might call itself again to
also obtain a lock in dst_wcroot */
- SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb, op_copy_txn, &ocb,
- scratch_pool));
+ SVN_WC__DB_WITH_TXN(op_copy_txn(ocb.src_wcroot, &ocb, scratch_pool),
+ ocb.src_wcroot);
return SVN_NO_ERROR;
}
@@ -5212,15 +5210,12 @@ db_op_copy_shadowed_layer(svn_wc__db_wcr
return SVN_NO_ERROR;
}
-/* Helper for svn_wc__db_op_copy_shadowed_layer().
- *
- * Implements svn_sqlite__transaction_callback_t. */
+/* Helper for svn_wc__db_op_copy_shadowed_layer(). */
static svn_error_t *
-op_copy_shadowed_layer_txn(void *baton,
- svn_sqlite__db_t *sdb,
+op_copy_shadowed_layer_txn(svn_wc__db_wcroot_t *wcroot,
+ struct op_copy_baton *ocb,
apr_pool_t *scratch_pool)
{
- struct op_copy_baton *ocb = baton;
const char *src_parent_relpath;
const char *dst_parent_relpath;
int src_op_depth;
@@ -5230,15 +5225,16 @@ op_copy_shadowed_layer_txn(void *baton,
apr_int64_t repos_id = INVALID_REPOS_ID;
svn_revnum_t revision = SVN_INVALID_REVNUM;
- if (sdb != ocb->dst_wcroot->sdb)
+ if (wcroot != ocb->dst_wcroot)
{
- /* Source and destination databases differ; so also start a lock
- in the destination database, by calling ourself in a lock. */
+ /* Source and destination databases differ; so also start a lock
+ in the destination database, by calling ourself in an extra lock. */
- return svn_error_trace(
- svn_sqlite__with_lock(ocb->dst_wcroot->sdb,
- op_copy_shadowed_layer_txn,
- ocb, scratch_pool));
+ SVN_WC__DB_WITH_TXN(op_copy_shadowed_layer_txn(ocb->dst_wcroot, ocb,
+ scratch_pool),
+ ocb->dst_wcroot);
+
+ return SVN_NO_ERROR;
}
/* From this point we can assume a lock in the src and dst databases */
@@ -5320,9 +5316,9 @@ svn_wc__db_op_copy_shadowed_layer(svn_wc
/* Call with the sdb in src_wcroot. It might call itself again to
also obtain a lock in dst_wcroot */
- SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb,
- op_copy_shadowed_layer_txn,
- &ocb, scratch_pool));
+ SVN_WC__DB_WITH_TXN(op_copy_shadowed_layer_txn(ocb.src_wcroot, &ocb,
+ scratch_pool),
+ ocb.src_wcroot);
return SVN_NO_ERROR;
}
@@ -11925,6 +11921,7 @@ svn_wc__db_lock_add(svn_wc__db_t *db,
static svn_error_t *
lock_remove_txn(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
const char *repos_relpath;
@@ -11944,6 +11941,8 @@ lock_remove_txn(svn_wc__db_wcroot_t *wcr
SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
return SVN_NO_ERROR;
}
@@ -11951,6 +11950,7 @@ lock_remove_txn(svn_wc__db_wcroot_t *wcr
svn_error_t *
svn_wc__db_lock_remove(svn_wc__db_t *db,
const char *local_abspath,
+ svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
svn_wc__db_wcroot_t *wcroot;
@@ -11963,7 +11963,7 @@ svn_wc__db_lock_remove(svn_wc__db_t *db,
VERIFY_USABLE_WCROOT(wcroot);
SVN_WC__DB_WITH_TXN(
- lock_remove_txn(wcroot, local_relpath, scratch_pool),
+ lock_remove_txn(wcroot, local_relpath, work_items, scratch_pool),
wcroot);
/* There may be some entries, and the lock info is now out of date. */
@@ -15521,3 +15521,514 @@ svn_wc__db_vacuum(svn_wc__db_t *db,
return SVN_NO_ERROR;
}
+
+/* Item queued with svn_wc__db_commit_queue_add */
+typedef struct commit_queue_item_t
+{
+ const char *local_relpath;
+ svn_boolean_t recurse; /* Use legacy recursion */
+ svn_boolean_t committed; /* Process the node as committed */
+ svn_boolean_t remove_lock; /* Remove existing lock on node */
+ svn_boolean_t remove_changelist; /* Remove changelist on node */
+
+ /* The pristine text checksum. NULL if the old value should be kept
+ and for directories */
+ const svn_checksum_t *new_sha1_checksum;
+
+ apr_hash_t *new_dav_cache; /* New DAV cache for the node */
+} commit_queue_item_t;
+
+/* The queue definition for vn_wc__db_create_commit_queue,
+ svn_wc__db_commit_queue_add and finally svn_wc__db_process_commit_queue */
+struct svn_wc__db_commit_queue_t
+{
+ svn_wc__db_wcroot_t *wcroot; /* Wcroot for ITEMS */
+ apr_array_header_t *items; /* List of commit_queue_item_t* */
+ svn_boolean_t have_recurse; /* Is one or more item[x]->recurse TRUE? */
+};
+
+/* Create a new svn_wc__db_commit_queue_t instance in RESULT_POOL for the
+ working copy specified with WRI_ABSPATH */
+svn_error_t *
+svn_wc__db_create_commit_queue(svn_wc__db_commit_queue_t **queue,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_wcroot_t *wcroot;
+ const char *local_relpath;
+ svn_wc__db_commit_queue_t *q;
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+ wri_abspath, result_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ q = apr_pcalloc(result_pool, sizeof(*q));
+
+ SVN_ERR_ASSERT(wcroot->sdb);
+
+ q->wcroot = wcroot;
+ q->items = apr_array_make(result_pool, 64,
+ sizeof(commit_queue_item_t*));
+ q->have_recurse = FALSE;
+
+ *queue = q;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_commit_queue_add(svn_wc__db_commit_queue_t *queue,
+ const char *local_abspath,
+ svn_boolean_t recurse,
+ svn_boolean_t is_commited,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const svn_checksum_t *new_sha1_checksum,
+ apr_hash_t *new_dav_cache,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ commit_queue_item_t *cqi;
+ const char *local_relpath;
+
+ local_relpath = svn_dirent_skip_ancestor(queue->wcroot->abspath,
+ local_abspath);
+
+ if (! local_relpath)
+ return svn_error_createf(
+ SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The path '%s' is not in the working copy '%s'"),
+ svn_dirent_local_style(local_abspath, scratch_pool),
+ svn_dirent_local_style(queue->wcroot->abspath, scratch_pool));
+
+ cqi = apr_pcalloc(result_pool, sizeof(*cqi));
+ cqi->local_relpath = local_relpath;
+ cqi->recurse = recurse;
+ cqi->committed = is_commited;
+ cqi->remove_lock = remove_lock;
+ cqi->remove_changelist = remove_changelist;
+ cqi->new_sha1_checksum = new_sha1_checksum;
+ cqi->new_dav_cache = new_dav_cache;
+
+ queue->have_recurse |= recurse;
+
+ APR_ARRAY_PUSH(queue->items, commit_queue_item_t *) = cqi;
+ return SVN_NO_ERROR;
+}
+
+/*** Finishing updates and commits. ***/
+
+/* Post process an item that is committed in the repository. Collapse layers into
+ * BASE. Queue work items that will finish a commit of the file or directory
+ * LOCAL_ABSPATH in DB:
+ */
+static svn_error_t *
+process_committed_leaf(svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_boolean_t via_recurse,
+ svn_wc__db_status_t status,
+ svn_node_kind_t kind,
+ svn_boolean_t prop_mods,
+ const svn_checksum_t *old_checksum,
+ svn_revnum_t new_revnum,
+ apr_time_t new_changed_date,
+ const char *new_changed_author,
+ apr_hash_t *new_dav_cache,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const svn_checksum_t *checksum,
+ apr_pool_t *scratch_pool)
+{
+ svn_revnum_t new_changed_rev = new_revnum;
+ svn_skel_t *work_item = NULL;
+
+ {
+ const char *lock_relpath;
+ svn_boolean_t locked;
+
+ if (kind == svn_node_dir)
+ lock_relpath = local_relpath;
+ else
+ lock_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
+
+ SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot,
+ lock_relpath, FALSE,
+ scratch_pool));
+
+ if (!locked)
+ return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
+ _("No write-lock in '%s'"),
+ path_for_error_message(wcroot, local_relpath,
+ scratch_pool));
+
+ SVN_ERR(flush_entries(wcroot, lock_relpath, svn_depth_empty,
+ scratch_pool));
+ }
+
+ if (status == svn_wc__db_status_deleted)
+ {
+ return svn_error_trace(
+ db_base_remove(wcroot, local_relpath, db,
+ FALSE /* keep_as_working */,
+ FALSE /* queue_deletes */,
+ TRUE /* remove_locks */,
+ (! via_recurse)
+ ? new_revnum : SVN_INVALID_REVNUM,
+ NULL, NULL,
+ scratch_pool));
+ }
+ else if (status == svn_wc__db_status_not_present)
+ {
+ /* We are committing the leaf of a copy operation.
+ We leave the not-present marker to allow pulling in excluded
+ children of a copy.
+
+ The next update will remove the not-present marker. */
+
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR_ASSERT(status == svn_wc__db_status_normal
+ || status == svn_wc__db_status_incomplete
+ || status == svn_wc__db_status_added);
+
+ if (kind != svn_node_dir)
+ {
+ /* If we sent a delta (meaning: post-copy modification),
+ then this file will appear in the queue and so we should have
+ its checksum already. */
+ if (checksum == NULL)
+ {
+ /* It was copied and not modified. We must have a text
+ base for it. And the node should have a checksum. */
+ SVN_ERR_ASSERT(old_checksum != NULL);
+
+ checksum = old_checksum;
+
+ /* Is the node completely unmodified and are we recursing? */
+ if (via_recurse && !prop_mods)
+ {
+ /* If a copied node itself is not modified, but the op_root of
+ the copy is committed we have to make sure that changed_rev,
+ changed_date and changed_author don't change or the working
+ copy used for committing will show different last modified
+ information then a clean checkout of exactly the same
+ revisions. (Issue #3676) */
+
+ SVN_ERR(svn_wc__db_read_info_internal(
+ NULL, NULL, NULL, NULL, NULL,
+ &new_changed_rev,
+ &new_changed_date,
+ &new_changed_author, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ wcroot, local_relpath,
+ scratch_pool, scratch_pool));
+ }
+ }
+
+ SVN_ERR(svn_wc__wq_build_file_commit(&work_item,
+ db, svn_dirent_join(wcroot->abspath,
+ local_relpath,
+ scratch_pool),
+ prop_mods,
+ scratch_pool, scratch_pool));
+ }
+
+ /* The new text base will be found in the pristine store by its checksum. */
+ SVN_ERR(commit_node(wcroot, local_relpath,
+ new_revnum, new_changed_rev,
+ new_changed_date, new_changed_author,
+ checksum,
+ NULL /* new_children */,
+ new_dav_cache,
+ !remove_changelist,
+ !remove_lock,
+ work_item,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/** Internal helper for svn_wc_process_committed_queue2().
+ * Bump a commit item, collapsing local changes with the new repository
+ * information to a new BASE node.
+ *
+ * @a new_date is the (server-side) date of the new revision, or 0.
+ *
+ * @a rev_author is the (server-side) author of the new
+ * revision; it may be @c NULL.
+ *
+ * @a new_dav_cache is a hash of all the new dav properties for LOCAL_RELPATH.
+ *
+ * If @a remove_lock is set, release any user locks on @a
+ * local_abspath; otherwise keep them during processing.
+ *
+ * If @a remove_changelist is set, clear any changeset assignments
+ * from @a local_abspath; otherwise, keep such assignments.
+ *
+ * If @a new_sha1_checksum is non-NULL, use it to identify the node's pristine
+ * text.
+ *
+ * Set TOP_OF_RECURSE to TRUE to show that this the top of a possibly
+ * recursive commit operation. (Part of the legacy recurse handling)
+ */
+static svn_error_t *
+process_committed_internal(svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_boolean_t recurse,
+ svn_boolean_t top_of_recurse,
+ svn_revnum_t new_revnum,
+ apr_time_t new_date,
+ const char *rev_author,
+ apr_hash_t *new_dav_cache,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const svn_checksum_t *new_sha1_checksum,
+ apr_hash_t *items_by_relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_status_t status;
+ svn_node_kind_t kind;
+ const svn_checksum_t *old_checksum;
+ svn_boolean_t prop_mods;
+
+ SVN_ERR(svn_wc__db_read_info_internal(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, &old_checksum, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, &prop_mods, NULL, NULL, NULL,
+ wcroot, local_relpath,
+ scratch_pool, scratch_pool));
+
+ /* NOTE: be wary of making crazy semantic changes in this function, since
+ svn_wc_process_committed4() calls this. */
+
+ SVN_ERR(process_committed_leaf(db, wcroot, local_relpath, !top_of_recurse,
+ status, kind, prop_mods, old_checksum,
+ new_revnum, new_date, rev_author,
+ new_dav_cache,
+ remove_lock, remove_changelist,
+ new_sha1_checksum,
+ scratch_pool));
+
+ /* Only check for recursion on nodes that have children */
+ if (kind != svn_node_dir
+ || status == svn_wc__db_status_not_present
+ || status == svn_wc__db_status_excluded
+ || status == svn_wc__db_status_server_excluded
+ /* Node deleted -> then no longer a directory */
+ || status == svn_wc__db_status_deleted)
+ {
+ return SVN_NO_ERROR;
+ }
+
+ if (recurse)
+ {
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int i;
+
+ /* Read PATH's entries; this is the absolute path. */
+ SVN_ERR(gather_children(&children, wcroot, local_relpath,
+ scratch_pool, iterpool));
+
+ /* Recursively loop over all children. */
+ for (i = 0; i < children->nelts; i++)
+ {
+ const char *name = APR_ARRAY_IDX(children, i, const char *);
+ const char *this_relpath;
+ const commit_queue_item_t *cqi;
+
+ svn_pool_clear(iterpool);
+
+ this_relpath = svn_dirent_join(local_relpath, name, iterpool);
+
+ new_sha1_checksum = NULL;
+ cqi = svn_hash_gets(items_by_relpath, this_relpath);
+
+ if (cqi != NULL)
+ new_sha1_checksum = cqi->new_sha1_checksum;
+
+ /* Recurse. Pass NULL for NEW_DAV_CACHE, because the
+ ones present in the current call are only applicable to
+ this one committed item. */
+ SVN_ERR(process_committed_internal(
+ db, wcroot, this_relpath,
+ TRUE /* recurse */,
+ FALSE /* top_of_recurse */,
+ new_revnum, new_date,
+ rev_author,
+ NULL /* new_dav_cache */,
+ FALSE /* remove_lock */,
+ remove_changelist,
+ new_sha1_checksum,
+ items_by_relpath,
+ iterpool));
+ }
+
+ svn_pool_destroy(iterpool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Return TRUE if any item of QUEUE is a parent of ITEM and will be
+ processed recursively, return FALSE otherwise.
+
+ The algorithmic complexity of this search implementation is O(queue
+ length), but it's quite quick.
+*/
+static svn_boolean_t
+have_recursive_parent(const apr_array_header_t *all_items,
+ const commit_queue_item_t *item,
+ apr_pool_t *scratch_pool)
+{
+ const char *local_relpath = item->local_relpath;
+ int i;
+
+ for (i = 0; i < all_items->nelts; i++)
+ {
+ const commit_queue_item_t *qi
+ = APR_ARRAY_IDX(all_items, i, const commit_queue_item_t *);
+
+ if (qi == item)
+ continue;
+
+ if (qi->recurse && svn_relpath_skip_ancestor(qi->local_relpath,
+ local_relpath))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* Compare function for svn_sort__array */
+static int
+compare_queue_items(const void *v1,
+ const void *v2)
+{
+ const commit_queue_item_t *cqi1
+ = *(const commit_queue_item_t **)v1;
+ const commit_queue_item_t *cqi2
+ = *(const commit_queue_item_t **)v2;
+
+ return svn_path_compare_paths(cqi1->local_relpath, cqi2->local_relpath);
+}
+
+/* Internal, locked version of svn_wc__db_process_commit_queue */
+static svn_error_t *
+db_process_commit_queue(svn_wc__db_t *db,
+ svn_wc__db_commit_queue_t *queue,
+ svn_revnum_t new_revnum,
+ apr_time_t new_date,
+ const char *new_author,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *items_by_relpath = NULL;
+ int j;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ svn_sort__array(queue->items, compare_queue_items);
+
+ if (queue->have_recurse)
+ {
+ items_by_relpath = apr_hash_make(scratch_pool);
+
+ for (j = 0; j < queue->items->nelts; j++)
+ {
+ commit_queue_item_t *cqi
+ = APR_ARRAY_IDX(queue->items, j, commit_queue_item_t *);
+
+ svn_hash_sets(items_by_relpath, cqi->local_relpath, cqi);
+ }
+ }
+
+ for (j = 0; j < queue->items->nelts; j++)
+ {
+ commit_queue_item_t *cqi
+ = APR_ARRAY_IDX(queue->items, j, commit_queue_item_t *);
+
+ svn_pool_clear(iterpool);
+
+ /* Skip this item if it is a child of a recursive item, because it has
+ been (or will be) accounted for when that recursive item was (or
+ will be) processed. */
+ if (queue->have_recurse && have_recursive_parent(queue->items, cqi,
+ iterpool))
+ continue;
+
+ if (!cqi->committed)
+ {
+ if (cqi->remove_lock)
+ {
+ svn_skel_t *work_item;
+
+ SVN_ERR(svn_wc__wq_build_sync_file_flags(
+ &work_item,
+ db,
+ svn_dirent_join(
+ queue->wcroot->abspath,
+ cqi->local_relpath,
+ iterpool),
+ iterpool, iterpool));
+
+ lock_remove_txn(queue->wcroot, cqi->local_relpath, work_item,
+ iterpool);
+ }
+ if (cqi->remove_changelist)
+ SVN_ERR(svn_wc__db_op_set_changelist(db,
+ svn_dirent_join(
+ queue->wcroot->abspath,
+ cqi->local_relpath,
+ iterpool),
+ NULL, NULL,
+ svn_depth_empty,
+ NULL, NULL, /* notify */
+ NULL, NULL, /* cancel */
+ iterpool));
+ }
+ else
+ {
+ SVN_ERR(process_committed_internal(
+ db, queue->wcroot, cqi->local_relpath,
+ cqi->recurse,
+ TRUE /* top_of_recurse */,
+ new_revnum, new_date, new_author,
+ cqi->new_dav_cache,
+ cqi->remove_lock,
+ cqi->remove_changelist,
+ cqi->new_sha1_checksum,
+ items_by_relpath,
+ iterpool));
+ }
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_process_commit_queue(svn_wc__db_t *db,
+ svn_wc__db_commit_queue_t *queue,
+ svn_revnum_t new_revnum,
+ apr_time_t new_date,
+ const char *new_author,
+ apr_pool_t *scratch_pool)
+{
+ SVN_WC__DB_WITH_TXN(db_process_commit_queue(db, queue,
+ new_revnum, new_date,
+ new_author, scratch_pool),
+ queue->wcroot);
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h Sat Jan 3 14:00:41 2015
@@ -1261,6 +1261,53 @@ svn_wc__db_committable_externals_below(a
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Opaque struct for svn_wc__db_create_commit_queue, svn_wc__db_commit_queue_add,
+ svn_wc__db_process_commit_queue */
+typedef struct svn_wc__db_commit_queue_t svn_wc__db_commit_queue_t;
+
+/* Create a new svn_wc__db_commit_queue_t instance in RESULT_POOL for the
+ working copy specified with WRI_ABSPATH */
+svn_error_t *
+svn_wc__db_create_commit_queue(svn_wc__db_commit_queue_t **queue,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Adds the specified path to the commit queue with the related information.
+
+ See svn_wc_queue_committed4() for argument documentation.
+
+ Note that this function currently DOESN'T copy the passed values to
+ RESULT_POOL, but expects them to be valid until processing. Otherwise the
+ only users memory requirements would +- double.
+ */
+svn_error_t *
+svn_wc__db_commit_queue_add(svn_wc__db_commit_queue_t *queue,
+ const char *local_abspath,
+ svn_boolean_t recurse,
+ svn_boolean_t is_commited,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const svn_checksum_t *new_sha1_checksum,
+ apr_hash_t *new_dav_cache,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Process the items in QUEUE in a single transaction. Commit workqueue items
+ for items that need post processing.
+
+ Implementation detail of svn_wc_process_committed_queue2().
+ */
+svn_error_t *
+svn_wc__db_process_commit_queue(svn_wc__db_t *db,
+ svn_wc__db_commit_queue_t *queue,
+ svn_revnum_t new_revnum,
+ apr_time_t new_date,
+ const char *new_author,
+ apr_pool_t *scratch_pool);
+
+
/* Gets a mapping from const char * local abspaths of externals to the const
char * local abspath of where they are defined for all externals defined
at or below LOCAL_ABSPATH.
@@ -2633,10 +2680,12 @@ svn_wc__db_lock_add(svn_wc__db_t *db,
apr_pool_t *scratch_pool);
-/* Remove any lock for LOCAL_ABSPATH in DB. */
+/* Remove any lock for LOCAL_ABSPATH in DB and install WORK_ITEMS
+ (if not NULL) in DB */
svn_error_t *
svn_wc__db_lock_remove(svn_wc__db_t *db,
const char *local_abspath,
+ svn_skel_t *work_items,
apr_pool_t *scratch_pool);
Modified: subversion/branches/authzperf/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/workqueue.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/workqueue.c Sat Jan 3 14:00:41 2015
@@ -1016,8 +1016,8 @@ svn_error_t *
svn_wc__wq_build_dir_install(svn_skel_t **work_item,
svn_wc__db_t *db,
const char *local_abspath,
- apr_pool_t *scratch_pool,
- apr_pool_t *result_pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
const char *local_relpath;
Modified: subversion/branches/authzperf/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/workqueue.h?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/workqueue.h Sat Jan 3 14:00:41 2015
@@ -215,8 +215,8 @@ svn_error_t *
svn_wc__wq_build_dir_install(svn_skel_t **work_item,
svn_wc__db_t *db,
const char *local_abspath,
- apr_pool_t *scratch_pool,
- apr_pool_t *result_pool);
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
svn_error_t *
svn_wc__wq_build_postupgrade(svn_skel_t **work_item,
Modified: subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c Sat Jan 3 14:00:41 2015
@@ -361,7 +361,7 @@ get_access_conf(request_rec *r, authz_sv
svn_error_t *svn_err = SVN_NO_ERROR;
dav_error *dav_err;
- dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_path);
+ dav_err = dav_svn_get_repos_path2(r, conf->base_path, &repos_path, scratch_pool);
if (dav_err)
{
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", dav_err->desc);
Modified: subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c Sat Jan 3 14:00:41 2015
@@ -323,7 +323,7 @@ db_open(apr_pool_t *p,
db->p = svn_pool_create(p);
/* ### temp hack */
- db->work = svn_stringbuf_ncreate("", 0, db->p);
+ db->work = svn_stringbuf_create_empty(db->p);
/* make our path-based authz callback available to svn_repos_* funcs. */
arb = apr_pcalloc(p, sizeof(*arb));
Modified: subversion/branches/authzperf/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/lock.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/lock.c Sat Jan 3 14:00:41 2015
@@ -787,7 +787,31 @@ append_locks(dav_lockdb *lockdb,
DAV_ERR_LOCK_SAVE_LOCK,
"Anonymous lock creation is not allowed.");
}
- else if (serr && (serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE ||
+ else if (serr && serr->apr_err == SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED)
+ {
+ /* The lock was created in the repository, so we should report the node
+ as locked to the client */
+
+ /* First log the hook failure, for diagnostics. This clears serr */
+ dav_svn__log_err(info->r,
+ dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+ "Post lock hook failure.",
+ resource->pool),
+ APLOG_WARNING);
+
+ /* How can we report the error to the client?
+
+ We can't return an error code, as that would make it impossible
+ to return the lock details?
+
+ Add yet another custom header?
+ Just an header doesn't handle a full error chain...
+
+ ### Current behavior: we don't report an error.
+ */
+
+ }
+ else if (serr && (svn_error_find_cause(serr, SVN_ERR_REPOS_HOOK_FAILURE) ||
serr->apr_err == SVN_ERR_FS_NO_SUCH_LOCK ||
serr->apr_err == SVN_ERR_FS_LOCK_EXPIRED ||
SVN_ERR_IS_LOCK_ERROR(serr)))
@@ -897,6 +921,22 @@ remove_lock(dav_lockdb *lockdb,
DAV_ERR_LOCK_SAVE_LOCK,
"Anonymous lock removal is not allowed.");
}
+ else if (serr && serr->apr_err == SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED
+ && !resource->info->repos->is_svn_client)
+ {
+ /* Generic DAV clients don't understand the specific error code we
+ would produce here as being just a warning, so lets produce a
+ success result. We removed the lock anyway. */
+
+ /* First log the hook failure, for diagnostics. This clears serr */
+ dav_svn__log_err(info->r,
+ dav_svn__convert_err(serr,
+ HTTP_INTERNAL_SERVER_ERROR,
+ "Post unlock hook failure.",
+ resource->pool),
+ APLOG_WARNING);
+
+ }
else if (serr)
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Failed to remove a lock.",
@@ -1016,7 +1056,7 @@ refresh_locks(dav_lockdb *lockdb,
DAV_ERR_LOCK_SAVE_LOCK,
"Anonymous lock refreshing is not allowed.");
}
- else if (serr && (serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE ||
+ else if (serr && (svn_error_find_cause(serr, SVN_ERR_REPOS_HOOK_FAILURE) ||
serr->apr_err == SVN_ERR_FS_NO_SUCH_LOCK ||
serr->apr_err == SVN_ERR_FS_LOCK_EXPIRED ||
SVN_ERR_IS_LOCK_ERROR(serr)))
Modified: subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c Sat Jan 3 14:00:41 2015
@@ -662,9 +662,10 @@ dav_svn__get_fs_parent_path(request_rec
AP_MODULE_DECLARE(dav_error *)
-dav_svn_get_repos_path(request_rec *r,
- const char *root_path,
- const char **repos_path)
+dav_svn_get_repos_path2(request_rec *r,
+ const char *root_path,
+ const char **repos_path,
+ apr_pool_t *pool)
{
const char *fs_path;
@@ -692,19 +693,26 @@ dav_svn_get_repos_path(request_rec *r,
/* Split the svn URI to get the name of the repository below
the parent path. */
- derr = dav_svn_split_uri(r, r->uri, root_path,
- &ignored_cleaned_uri, &ignored_had_slash,
- &repos_name,
- &ignored_relative, &ignored_path_in_repos);
+ derr = dav_svn_split_uri2(r, r->uri, root_path,
+ &ignored_cleaned_uri, &ignored_had_slash,
+ &repos_name,
+ &ignored_relative, &ignored_path_in_repos, pool);
if (derr)
return derr;
/* Construct the full path from the parent path base directory
and the repository name. */
- *repos_path = svn_dirent_join(fs_parent_path, repos_name, r->pool);
+ *repos_path = svn_dirent_join(fs_parent_path, repos_name, pool);
return NULL;
}
+AP_MODULE_DECLARE(dav_error *)
+dav_svn_get_repos_path(request_rec *r,
+ const char *root_path,
+ const char **repos_path)
+{
+ return dav_svn_get_repos_path2(r, root_path, repos_path, r->pool);
+}
const char *
dav_svn__get_repo_name(request_rec *r)
@@ -1324,8 +1332,8 @@ static const command_rec cmds[] =
AP_INIT_TAKE1("SVNInMemoryCacheSize", SVNInMemoryCacheSize_cmd, NULL,
RSRC_CONF,
"specifies the maximum size in kB per process of Subversion's "
- "in-memory object cache (default value is 16384; 0 deactivates "
- "the cache)."),
+ "in-memory object cache (default value is 16384; 0 switches "
+ "to dynamically sized caches)."),
/* per server */
AP_INIT_TAKE1("SVNCompressionLevel", SVNCompressionLevel_cmd, NULL,
RSRC_CONF,
Modified: subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c Sat Jan 3 14:00:41 2015
@@ -56,6 +56,9 @@ dav_svn__get_deleted_rev_report(const da
dav_error *derr = NULL;
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
if (ns == -1)
return dav_svn__new_error_svn(resource->pool, HTTP_BAD_REQUEST, 0,