You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sb...@apache.org on 2012/06/16 23:15:22 UTC
svn commit: r1351009 - in /subversion/trunk/subversion: include/
libsvn_repos/ svndumpfilter/ svnrdump/ tests/cmdline/
tests/cmdline/svndumpfilter_tests_data/
Author: sbutler
Date: Sat Jun 16 21:15:22 2012
New Revision: 1351009
URL: http://svn.apache.org/viewvc?rev=1351009&view=rev
Log:
Accept dump format v3, except for property deltas, in svndumpfilter.
Replace the hardcoded version number ("2") with a parser callback for
the dump file format version number. Used by svndumpfilter only (so
far).
Add an API option to treat text-deltas as text instead of applying
them. TRUE for svndumpfilter only.
* subversion/tests/cmdline/svndumpfilter_tests.py
(with_deltas): New test.
(test_list): Add the test.
* subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
New file.
* subversion/include/svn_repos.h
(magic_header_record): New callback declaration.
(svn_repos_parse_fns3_t): Add the new callback declaration.
(svn_repos_parse_dumpstream3): Add the text-delta option.
* subversion/libsvn_repos/load.c
(parse_format_version): While we're here, put the "output" argument
first.
(svn_repos_parse_dumpstream3): Implement the text-delta-as-text option.
Pass the format version to the new callback. Don't reject v3 dumpfiles
anymore.
* subversion/svndumpfilter/main.c
(magic_header_record): New callback.
(svn_repos_parse_fns3_t): Add the new callback.
(parse_baton_initialize): Remove the hard-coded format-version output.
(do_filter): Treat text-deltas as text.
* subversion/svnrdump/load_editor.c
(magic_header_record): New callback.
(svn_rdump__load_dumpstream): Use the new callback.
* subversion/libsvn_repos/deprecated.c
(fns3_from_fns2): Set the new callback.
(svn_repos_get_fs_build_parser3): Add the text-delta option.
* subversion/libsvn_repos/load-fs-vtable.c
(magic_header_record): New callback.
(svn_repos_get_fs_build_parser4): Use the new callback.
(svn_repos_load_fs4): Add the text-delta option.
Added:
subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
Modified:
subversion/trunk/subversion/include/svn_repos.h
subversion/trunk/subversion/libsvn_repos/deprecated.c
subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c
subversion/trunk/subversion/libsvn_repos/load.c
subversion/trunk/subversion/svndumpfilter/main.c
subversion/trunk/subversion/svnrdump/load_editor.c
subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py
Modified: subversion/trunk/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Sat Jun 16 21:15:22 2012
@@ -2706,12 +2706,19 @@ svn_repos_load_fs(svn_repos_t *repos,
/**
* A vtable that is driven by svn_repos_parse_dumpstream3().
- * ### TODO: Add a new callback for the dumpfile version header.
*
* @since New in 1.8.
*/
typedef struct svn_repos_parse_fns3_t
{
+ /** The parser has discovered a new "magic header" record within the
+ * parsing session represented by @a parse_baton. The dump-format
+ * version number is @a version.
+ */
+ svn_error_t *(*magic_header_record)(int version,
+ void *parse_baton,
+ apr_pool_t *pool);
+
/** The parser has discovered a new uuid record within the parsing
* session represented by @a parse_baton. The uuid's value is
* @a uuid, and it is allocated in @a pool.
@@ -2801,8 +2808,10 @@ typedef struct svn_repos_parse_fns3_t
* Read and parse dumpfile-formatted @a stream, calling callbacks in
* @a parse_fns/@a parse_baton, and using @a pool for allocations.
*
- * ### TODO: Add a boolean option to treat text-deltas as text, because
- * a dump-filtering tool shouldn't apply the deltas.
+ * If @a deltas_are_text is @c TRUE, handle text-deltas with the @a
+ * set_fulltext callback. This is useful when manipulating a dump
+ * stream without loading it. Otherwise handle text-deltas with the
+ * @a apply_textdelta callback.
*
* If @a cancel_func is not @c NULL, it is called periodically with
* @a cancel_baton as argument to see if the client wishes to cancel
@@ -2811,7 +2820,7 @@ typedef struct svn_repos_parse_fns3_t
* This parser has built-in knowledge of the dumpfile format, but only
* in a limited sense:
*
- * * ### TODO: it recognizes the "magic" format-version header.
+ * * it recognizes the "magic" format-version header.
*
* * it recognizes the UUID header.
*
@@ -2825,7 +2834,8 @@ typedef struct svn_repos_parse_fns3_t
* and text, and pass the pieces to the vtable.
*
* This is enough knowledge to make it easy on vtable implementors,
- * but still allow expansion of the format: most headers are ignored.
+ * but still allow expansion of the format: most headers do not have
+ * to be handled explicitly.
*
* @since New in 1.8.
*/
@@ -2833,6 +2843,7 @@ svn_error_t *
svn_repos_parse_dumpstream3(svn_stream_t *stream,
const svn_repos_parse_fns3_t *parse_fns,
void *parse_baton,
+ svn_boolean_t deltas_are_text,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool);
Modified: subversion/trunk/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/deprecated.c?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_repos/deprecated.c Sat Jun 16 21:15:22 2012
@@ -824,6 +824,7 @@ fns3_from_fns2(const svn_repos_parser_fn
svn_repos_parse_fns3_t *fns3;
fns3 = apr_palloc(pool, sizeof(*fns3));
+ fns3->magic_header_record = NULL;
fns3->uuid_record = fns2->uuid_record;
fns3->new_revision_record = fns2->new_revision_record;
fns3->new_node_record = fns2->new_node_record;
@@ -848,7 +849,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
{
svn_repos_parse_fns3_t *fns3 = fns3_from_fns2(parse_fns, pool);
- return svn_repos_parse_dumpstream3(stream, fns3, parse_baton,
+ return svn_repos_parse_dumpstream3(stream, fns3, parse_baton, FALSE,
cancel_func, cancel_baton, pool);
}
Modified: subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c Sat Jun 16 21:15:22 2012
@@ -589,6 +589,13 @@ maybe_add_with_history(struct node_baton
return SVN_NO_ERROR;
}
+static svn_error_t *
+magic_header_record(int version,
+ void *parse_baton,
+ apr_pool_t *pool)
+{
+ return SVN_NO_ERROR;
+}
static svn_error_t *
uuid_record(const char *uuid,
@@ -1042,6 +1049,7 @@ svn_repos_get_fs_build_parser4(const svn
if (SVN_IS_VALID_REVNUM(start_rev))
SVN_ERR_ASSERT(start_rev <= end_rev);
+ parser->magic_header_record = magic_header_record;
parser->uuid_record = uuid_record;
parser->new_revision_record = new_revision_record;
parser->new_node_record = new_node_record;
@@ -1116,6 +1124,6 @@ svn_repos_load_fs4(svn_repos_t *repos,
pb->use_pre_commit_hook = use_pre_commit_hook;
pb->use_post_commit_hook = use_post_commit_hook;
- return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton,
+ return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton, FALSE,
cancel_func, cancel_baton, pool);
}
Modified: subversion/trunk/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/load.c?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/load.c (original)
+++ subversion/trunk/subversion/libsvn_repos/load.c Sat Jun 16 21:15:22 2012
@@ -373,7 +373,8 @@ parse_text_block(svn_stream_t *stream,
/* Parse VERSIONSTRING and verify that we support the dumpfile format
version number, setting *VERSION appropriately. */
static svn_error_t *
-parse_format_version(const char *versionstring, int *version)
+parse_format_version(int *version,
+ const char *versionstring)
{
static const int magic_len = sizeof(SVN_REPOS_DUMPFILE_MAGIC_HEADER) - 1;
const char *p = strchr(versionstring, ':');
@@ -409,6 +410,7 @@ svn_error_t *
svn_repos_parse_dumpstream3(svn_stream_t *stream,
const svn_repos_parse_fns3_t *parse_fns,
void *parse_baton,
+ svn_boolean_t deltas_are_text,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
@@ -428,16 +430,11 @@ svn_repos_parse_dumpstream3(svn_stream_t
return stream_ran_dry();
/* The first two lines of the stream are the dumpfile-format version
- number, and a blank line. */
- SVN_ERR(parse_format_version(linebuf->data, &version));
-
- /* If we were called from svn_repos_parse_dumpstream(), the
- callbacks to handle delta contents will be NULL, so we have to
- reject dumpfiles with the current version. */
- if (version == SVN_REPOS_DUMPFILE_FORMAT_VERSION
- && (!parse_fns->delete_node_property || !parse_fns->apply_textdelta))
- return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
- _("Unsupported dumpfile version: %d"), version);
+ number, and a blank line. To preserve backward compatibility,
+ don't assume the existence of newer parser-vtable functions. */
+ SVN_ERR(parse_format_version(&version, linebuf->data));
+ if (parse_fns->magic_header_record != NULL)
+ SVN_ERR(parse_fns->magic_header_record(version, parse_baton, pool));
/* A dumpfile "record" is defined to be a header-block of
rfc822-style headers, possibly followed by a content-block.
@@ -528,6 +525,7 @@ svn_repos_parse_dumpstream3(svn_stream_t
SVN_ERR(parse_fns->uuid_record(value, parse_baton, pool));
}
/* Or perhaps a dumpfile format? */
+ /* ### TODO: use parse_format_version */
else if ((value = apr_hash_get(headers,
SVN_REPOS_DUMPFILE_MAGIC_HEADER,
APR_HASH_KEY_STRING)))
@@ -591,7 +589,9 @@ svn_repos_parse_dumpstream3(svn_stream_t
const char *delta = apr_hash_get(headers,
SVN_REPOS_DUMPFILE_TEXT_DELTA,
APR_HASH_KEY_STRING);
- svn_boolean_t is_delta = (delta && strcmp(delta, "true") == 0);
+ svn_boolean_t is_delta = FALSE;
+ if (! deltas_are_text)
+ is_delta = (delta && strcmp(delta, "true") == 0);
SVN_ERR(parse_text_block(stream,
svn__atoui64(text_cl),
Modified: subversion/trunk/subversion/svndumpfilter/main.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svndumpfilter/main.c?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/svndumpfilter/main.c (original)
+++ subversion/trunk/subversion/svndumpfilter/main.c Sat Jun 16 21:15:22 2012
@@ -256,6 +256,19 @@ struct node_baton_t
/* Filtering vtable members */
+/* File-format stamp. */
+static svn_error_t *
+magic_header_record(int version, void *parse_baton, apr_pool_t *pool)
+{
+ struct parse_baton_t *pb = parse_baton;
+ SVN_ERR(svn_stream_printf(pb->out_stream, pool,
+ SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
+ version));
+
+ return SVN_NO_ERROR;
+}
+
+
/* New revision: set up revision_baton, decide if we skip it. */
static svn_error_t *
new_revision_record(void **revision_baton,
@@ -880,6 +893,7 @@ close_revision(void *revision_baton)
/* Filtering vtable */
svn_repos_parse_fns3_t filtering_vtable =
{
+ magic_header_record,
uuid_record,
new_revision_record,
new_node_record,
@@ -1032,17 +1046,6 @@ parse_baton_initialize(struct parse_bato
baton->last_live_revision = SVN_INVALID_REVNUM;
baton->oldest_original_rev = SVN_INVALID_REVNUM;
- /* This is non-ideal: We should pass through the version of the
- * input dumpstream. However, our API currently doesn't allow that.
- * Hardcoding version 2 is acceptable because:
- * - We currently do not accept version 3 or greater.
- * - Dumpstream version 1 is so ancient as to be ignorable
- * (0.17.x and earlier)
- */
- SVN_ERR(svn_stream_printf(baton->out_stream, pool,
- SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
- 2));
-
*pb = baton;
return SVN_NO_ERROR;
}
@@ -1145,7 +1148,7 @@ do_filter(apr_getopt_t *os,
SVN_ERR(parse_baton_initialize(&pb, opt_state, do_exclude, pool));
SVN_ERR(svn_repos_parse_dumpstream3(pb->in_stream, &filtering_vtable, pb,
- NULL, NULL, pool));
+ TRUE, NULL, NULL, pool));
/* The rest of this is just reporting. If we aren't reporting, get
outta here. */
Modified: subversion/trunk/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/load_editor.c?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/load_editor.c (original)
+++ subversion/trunk/subversion/svnrdump/load_editor.c Sat Jun 16 21:15:22 2012
@@ -584,6 +584,14 @@ new_revision_record(void **revision_bato
}
static svn_error_t *
+magic_header_record(int version,
+ void *parse_baton,
+ apr_pool_t *pool)
+{
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
uuid_record(const char *uuid,
void *parse_baton,
apr_pool_t *pool)
@@ -1163,8 +1171,9 @@ svn_rdump__load_dumpstream(svn_stream_t
session_url, pool));
parser = apr_pcalloc(pool, sizeof(*parser));
- parser->new_revision_record = new_revision_record;
+ parser->magic_header_record = magic_header_record;
parser->uuid_record = uuid_record;
+ parser->new_revision_record = new_revision_record;
parser->new_node_record = new_node_record;
parser->set_revision_property = set_revision_property;
parser->set_node_property = set_node_property;
@@ -1185,7 +1194,7 @@ svn_rdump__load_dumpstream(svn_stream_t
parse_baton->last_rev_mapped = SVN_INVALID_REVNUM;
parse_baton->oldest_dumpstream_rev = SVN_INVALID_REVNUM;
- err = svn_repos_parse_dumpstream3(stream, parser, parse_baton,
+ err = svn_repos_parse_dumpstream3(stream, parser, parse_baton, FALSE,
cancel_func, cancel_baton, pool);
/* If all goes well, or if we're cancelled cleanly, don't leave a
Modified: subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1351009&r1=1351008&r2=1351009&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py Sat Jun 16 21:15:22 2012
@@ -33,8 +33,9 @@ import tempfile
import svntest
from svntest.verify import SVNExpectedStdout, SVNExpectedStderr
-# Get some helper routines from svnadmin_tests
+# Get some helper routines
from svnadmin_tests import load_and_verify_dumpstream, test_create
+from svntest.main import run_svn, run_svnadmin
# (abbreviation)
Skip = svntest.testcase.Skip_deco
@@ -651,6 +652,23 @@ def match_empty_prefix(sbox):
# doesn't seem to be a consistent way to quote such an argument to
# prevent expansion.
+@Issue(2760)
+def accepts_deltas(sbox):
+ "accepts deltas in the input"
+ # Accept format v3 (as created by 'svnadmin --deltas' or svnrdump).
+
+ test_create(sbox)
+ dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
+ 'svndumpfilter_tests_data',
+ 'simple_v3.dump')
+ dumpfile = open(dumpfile_location).read()
+
+ filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include",
+ "trunk", "--quiet")
+ load_and_verify_dumpstream(sbox, [], [], None, filtered_out)
+
+
+
########################################################################
# Run the tests
@@ -664,6 +682,7 @@ test_list = [ None,
filter_mergeinfo_revs_outside_of_dump_stream,
dropped_but_not_renumbered_empty_revs,
match_empty_prefix,
+ accepts_deltas,
]
if __name__ == '__main__':
Added: subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump?rev=1351009&view=auto
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump (added)
+++ subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump Sat Jun 16 21:15:22 2012
@@ -0,0 +1,71 @@
+SVN-fs-dump-format-version: 3
+
+UUID: 95ae2ea4-9df8-40f9-8aee-3e2af6f6aa3c
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2012-06-15T15:58:51.002886Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 103
+Content-length: 103
+
+K 10
+svn:author
+V 7
+jrandom
+K 8
+svn:date
+V 27
+2012-06-15T16:00:19.178493Z
+K 7
+svn:log
+V 4
+Test
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 41
+Content-length: 41
+
+K 4
+soup
+V 16
+No soup for you.
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 114
+Content-length: 114
+
+K 10
+svn:author
+V 7
+jrandom
+K 8
+svn:date
+V 27
+2012-06-15T16:01:26.311580Z
+K 7
+svn:log
+V 14
+Create branch
+
+PROPS-END
+
+Node-path: branch1
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+
+