summaryrefslogtreecommitdiff
path: root/subversion/libsvn_repos
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_repos')
-rw-r--r--subversion/libsvn_repos/commit.c7
-rw-r--r--subversion/libsvn_repos/load-fs-vtable.c207
-rw-r--r--subversion/libsvn_repos/rev_hunt.c31
3 files changed, 161 insertions, 84 deletions
diff --git a/subversion/libsvn_repos/commit.c b/subversion/libsvn_repos/commit.c
index 77fe84647173d..22cf873b31cfe 100644
--- a/subversion/libsvn_repos/commit.c
+++ b/subversion/libsvn_repos/commit.c
@@ -777,6 +777,13 @@ close_edit(void *edit_baton,
post_commit_err = svn_repos__post_commit_error_str(err, pool);
svn_error_clear(err);
}
+
+ /* Make sure a future abort doesn't perform
+ any work. This may occur if the commit
+ callback returns an error! */
+
+ eb->txn = NULL;
+ eb->txn_root = NULL;
}
else
{
diff --git a/subversion/libsvn_repos/load-fs-vtable.c b/subversion/libsvn_repos/load-fs-vtable.c
index c8c5e95d5101b..d1aa339d7c110 100644
--- a/subversion/libsvn_repos/load-fs-vtable.c
+++ b/subversion/libsvn_repos/load-fs-vtable.c
@@ -40,6 +40,7 @@
#include <apr_lib.h>
+#include "private/svn_repos_private.h"
#include "private/svn_fspath.h"
#include "private/svn_dep_compat.h"
#include "private/svn_mergeinfo_private.h"
@@ -61,7 +62,7 @@ struct parse_baton
const char *parent_dir; /* repository relpath, or NULL */
svn_repos_notify_func_t notify_func;
void *notify_baton;
- svn_repos_notify_t *notify;
+ apr_pool_t *notify_pool; /* scratch pool for notifications */
apr_pool_t *pool;
/* Start and end (inclusive) of revision range we'll pay attention
@@ -329,16 +330,7 @@ renumber_mergeinfo_revs(svn_string_t **final_val,
SVN_ERR(svn_mergeinfo_merge2(final_mergeinfo, predates_stream_mergeinfo,
subpool, subpool));
- SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
-
- /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0
- or r1. However, svndumpfilter can be abused to produce r1 merge source
- revs. So if we encounter any, then strip them out, no need to put them
- into the load target. */
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&final_mergeinfo,
- final_mergeinfo,
- 1, 0, FALSE,
- subpool, subpool));
+ SVN_ERR(svn_mergeinfo__canonicalize_ranges(final_mergeinfo, subpool));
SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool));
svn_pool_destroy(subpool);
@@ -502,9 +494,14 @@ new_revision_record(void **revision_baton,
if (pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_txn_start;
- pb->notify->old_revision = rb->rev;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_txn_start,
+ pb->notify_pool);
+
+ notify->old_revision = rb->rev;
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
/* Stash the oldest "old" revision committed from the load stream. */
@@ -515,9 +512,14 @@ new_revision_record(void **revision_baton,
/* If we're skipping this revision, try to notify someone. */
if (rb->skipped && pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_skipped_rev;
- pb->notify->old_revision = rb->rev;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_skipped_rev,
+ pb->notify_pool);
+
+ notify->old_revision = rb->rev;
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
/* If we're parsing revision 0, only the revision are (possibly)
@@ -586,8 +588,13 @@ maybe_add_with_history(struct node_baton *nb,
if (pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_copied_node;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_copied_node,
+ pb->notify_pool);
+
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
}
@@ -656,10 +663,14 @@ new_node_record(void **node_baton,
if (pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_node_start;
- pb->notify->node_action = nb->action;
- pb->notify->path = nb->path;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_node_start,
+ pb->notify_pool);
+
+ notify->path = nb->path;
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
switch (nb->action)
@@ -726,6 +737,67 @@ set_revision_property(void *baton,
}
+/* Adjust mergeinfo:
+ * - normalize line endings (if all CRLF, change to LF; but error if mixed);
+ * - adjust revision numbers (see renumber_mergeinfo_revs());
+ * - adjust paths (see prefix_mergeinfo_paths()).
+ */
+static svn_error_t *
+adjust_mergeinfo_property(struct revision_baton *rb,
+ svn_string_t **new_value_p,
+ const svn_string_t *old_value,
+ apr_pool_t *result_pool)
+{
+ struct parse_baton *pb = rb->pb;
+ svn_string_t prop_val = *old_value;
+
+ /* Tolerate mergeinfo with "\r\n" line endings because some
+ dumpstream sources might contain as much. If so normalize
+ the line endings to '\n' and make a notification to
+ PARSE_BATON->FEEDBACK_STREAM that we have made this
+ correction. */
+ if (strstr(prop_val.data, "\r"))
+ {
+ const char *prop_eol_normalized;
+
+ SVN_ERR(svn_subst_translate_cstring2(prop_val.data,
+ &prop_eol_normalized,
+ "\n", /* translate to LF */
+ FALSE, /* no repair */
+ NULL, /* no keywords */
+ FALSE, /* no expansion */
+ result_pool));
+ prop_val.data = prop_eol_normalized;
+ prop_val.len = strlen(prop_eol_normalized);
+
+ if (pb->notify_func)
+ {
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify
+ = svn_repos_notify_create(
+ svn_repos_notify_load_normalized_mergeinfo,
+ pb->notify_pool);
+
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
+ }
+ }
+
+ /* Renumber mergeinfo as appropriate. */
+ SVN_ERR(renumber_mergeinfo_revs(new_value_p, &prop_val, rb,
+ result_pool));
+ if (pb->parent_dir)
+ {
+ /* Prefix the merge source paths with PB->parent_dir. */
+ /* ASSUMPTION: All source paths are included in the dump stream. */
+ SVN_ERR(prefix_mergeinfo_paths(new_value_p, *new_value_p,
+ pb->parent_dir, result_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
static svn_error_t *
set_node_property(void *baton,
const char *name,
@@ -739,51 +811,42 @@ set_node_property(void *baton,
if (rb->skipped)
return SVN_NO_ERROR;
+ /* Adjust mergeinfo. If this fails, presumably because the mergeinfo
+ property has an ill-formed value, then we must not fail to load
+ the repository (at least if it's a simple load with no revision
+ offset adjustments, path changes, etc.) so just warn and leave it
+ as it is. */
if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
- svn_string_t *renumbered_mergeinfo;
- /* ### Need to cast away const. We cannot change the declaration of
- * ### this function since it is part of svn_repos_parse_fns2_t. */
- svn_string_t *prop_val = (svn_string_t *)value;
-
- /* Tolerate mergeinfo with "\r\n" line endings because some
- dumpstream sources might contain as much. If so normalize
- the line endings to '\n' and make a notification to
- PARSE_BATON->FEEDBACK_STREAM that we have made this
- correction. */
- if (strstr(prop_val->data, "\r"))
- {
- const char *prop_eol_normalized;
-
- SVN_ERR(svn_subst_translate_cstring2(prop_val->data,
- &prop_eol_normalized,
- "\n", /* translate to LF */
- FALSE, /* no repair */
- NULL, /* no keywords */
- FALSE, /* no expansion */
- nb->pool));
- prop_val->data = prop_eol_normalized;
- prop_val->len = strlen(prop_eol_normalized);
+ svn_string_t *new_value;
+ svn_error_t *err;
+ err = adjust_mergeinfo_property(rb, &new_value, value, nb->pool);
+ if (err)
+ {
+ if (pb->validate_props)
+ {
+ return svn_error_quick_wrap(
+ err,
+ _("Invalid svn:mergeinfo value"));
+ }
if (pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_normalized_mergeinfo;
- pb->notify_func(pb->notify_baton, pb->notify, nb->pool);
+ svn_repos_notify_t *notify
+ = svn_repos_notify_create(svn_repos_notify_warning,
+ pb->notify_pool);
+
+ notify->warning = svn_repos__notify_warning_invalid_mergeinfo;
+ notify->warning_str = _("Invalid svn:mergeinfo value; "
+ "leaving unchanged");
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
+ svn_error_clear(err);
}
-
- /* Renumber mergeinfo as appropriate. */
- SVN_ERR(renumber_mergeinfo_revs(&renumbered_mergeinfo, prop_val, rb,
- nb->pool));
- value = renumbered_mergeinfo;
- if (pb->parent_dir)
+ else
{
- /* Prefix the merge source paths with PB->parent_dir. */
- /* ASSUMPTION: All source paths are included in the dump stream. */
- svn_string_t *mergeinfo_val;
- SVN_ERR(prefix_mergeinfo_paths(&mergeinfo_val, value,
- pb->parent_dir, nb->pool));
- value = mergeinfo_val;
+ value = new_value;
}
}
@@ -896,8 +959,13 @@ close_node(void *baton)
if (pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_node_done;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_node_done,
+ pb->notify_pool);
+
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
return SVN_NO_ERROR;
@@ -1016,12 +1084,17 @@ close_revision(void *baton)
if (pb->notify_func)
{
- pb->notify->action = svn_repos_notify_load_txn_committed;
- pb->notify->new_revision = committed_rev;
- pb->notify->old_revision = ((committed_rev == rb->rev)
+ /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_txn_committed,
+ pb->notify_pool);
+
+ notify->new_revision = committed_rev;
+ notify->old_revision = ((committed_rev == rb->rev)
? SVN_INVALID_REVNUM
: rb->rev);
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
+ svn_pool_clear(pb->notify_pool);
}
return SVN_NO_ERROR;
@@ -1079,10 +1152,10 @@ svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks,
pb->validate_props = validate_props;
pb->notify_func = notify_func;
pb->notify_baton = notify_baton;
- pb->notify = svn_repos_notify_create(svn_repos_notify_load_txn_start, pool);
pb->uuid_action = uuid_action;
pb->parent_dir = parent_dir;
pb->pool = pool;
+ pb->notify_pool = svn_pool_create(pool);
pb->rev_map = apr_hash_make(pool);
pb->oldest_old_rev = SVN_INVALID_REVNUM;
pb->last_rev_mapped = SVN_INVALID_REVNUM;
diff --git a/subversion/libsvn_repos/rev_hunt.c b/subversion/libsvn_repos/rev_hunt.c
index 77b1f2a7d74de..2a8dc3ee9d320 100644
--- a/subversion/libsvn_repos/rev_hunt.c
+++ b/subversion/libsvn_repos/rev_hunt.c
@@ -726,23 +726,6 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
if (! prev_path)
break;
- if (authz_read_func)
- {
- svn_boolean_t readable;
- svn_fs_root_t *tmp_root;
-
- SVN_ERR(svn_fs_revision_root(&tmp_root, fs, revision, currpool));
- SVN_ERR(authz_read_func(&readable, tmp_root, path,
- authz_read_baton, currpool));
- if (! readable)
- {
- svn_pool_destroy(lastpool);
- svn_pool_destroy(currpool);
-
- return SVN_NO_ERROR;
- }
- }
-
/* Assign the current path to all younger revisions until we reach
the copy target rev. */
while ((revision_ptr < revision_ptr_end)
@@ -765,6 +748,20 @@ svn_repos_trace_node_locations(svn_fs_t *fs,
path = prev_path;
revision = prev_rev;
+ if (authz_read_func)
+ {
+ svn_boolean_t readable;
+ SVN_ERR(svn_fs_revision_root(&root, fs, revision, currpool));
+ SVN_ERR(authz_read_func(&readable, root, path,
+ authz_read_baton, currpool));
+ if (!readable)
+ {
+ svn_pool_destroy(lastpool);
+ svn_pool_destroy(currpool);
+ return SVN_NO_ERROR;
+ }
+ }
+
/* Clear last pool and switch. */
svn_pool_clear(lastpool);
tmppool = lastpool;