Author: sbutler
Date: Mon Jun 25 21:07:37 2012
New Revision: 1353745
URL: http://svn.apache.org/viewvc?rev=1353745&view=rev
Log:
Support property deltas in svndumpfilter.
* subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
Extend with a revision containing propdeltas (added and deleted).
* subversion/tests/cmdine/svndumpfilter_tests.py
(accepts_deltas): Check that the prop deltas are preserved.
* subversion/include/svn_repos.h
(SVN_REPOS_DUMPFILE_FORMAT_VERSION_DELTAS): New #define.
* subversion/svndumpfilter/main.c
(write_propdel_to_stringbuf): New function.
(parse_baton_t): Add 'allow_deltas' flag.
(node_baton_t): Add fields for delta parsing.
(magic_header_record): Allow deltas for v3 or higher.
(new_node_record): Prepare to parse deltas if necessary.
(set_node_property): Allow prop deltas.
(delete_node_property): New callback implementation.
(filtering_vtable): Use the new callback.
(parse_baton_initialize): Set deltas off by default.
Modified:
subversion/trunk/subversion/include/svn_repos.h
subversion/trunk/subversion/svndumpfilter/main.c
subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py
subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
Modified: subversion/trunk/subversion/include/svn_repos.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1353745&r1=1353744&r2=1353745&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Mon Jun 25 21:07:37 2012
@@ -2404,6 +2404,7 @@ svn_repos_node_from_baton(void *edit_bat
/* The RFC822-style headers in our dumpfile format. */
#define SVN_REPOS_DUMPFILE_MAGIC_HEADER "SVN-fs-dump-format-version"
#define SVN_REPOS_DUMPFILE_FORMAT_VERSION 3
+#define SVN_REPOS_DUMPFILE_FORMAT_VERSION_DELTAS 3
#define SVN_REPOS_DUMPFILE_UUID "UUID"
#define SVN_REPOS_DUMPFILE_CONTENT_LENGTH "Content-length"
Modified: subversion/trunk/subversion/svndumpfilter/main.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svndumpfilter/main.c?rev=1353745&r1=1353744&r2=1353745&view=diff
==============================================================================
--- subversion/trunk/subversion/svndumpfilter/main.c (original)
+++ subversion/trunk/subversion/svndumpfilter/main.c Mon Jun 25 21:07:37 2012
@@ -110,6 +110,28 @@ write_prop_to_stringbuf(svn_stringbuf_t
}
+/* Writes a property deletion in dumpfile format to given stringbuf. */
+static void
+write_propdel_to_stringbuf(svn_stringbuf_t **strbuf,
+ const char *name)
+{
+ int bytes_used;
+ size_t namelen;
+ char buf[SVN_KEYLINE_MAXLEN];
+
+ /* Output name length, then name. */
+ namelen = strlen(name);
+ svn_stringbuf_appendbytes(*strbuf, "D ", 2);
+
+ bytes_used = apr_snprintf(buf, sizeof(buf), "%" APR_SIZE_T_FMT, namelen);
+ svn_stringbuf_appendbytes(*strbuf, buf, bytes_used);
+ svn_stringbuf_appendbyte(*strbuf, '\n');
+
+ svn_stringbuf_appendbytes(*strbuf, name, namelen);
+ svn_stringbuf_appendbyte(*strbuf, '\n');
+}
+
+
/* Compare the node-path PATH with the (const char *) prefixes in PFXLIST.
* Return TRUE if any prefix is a prefix of PATH (matching whole path
* components); FALSE otherwise.
@@ -187,6 +209,7 @@ struct parse_baton_t
svn_boolean_t do_renumber_revs;
svn_boolean_t preserve_revprops;
svn_boolean_t skip_missing_merge_sources;
+ svn_boolean_t allow_deltas;
apr_array_header_t *prefixes;
/* Input and output streams. */
@@ -250,6 +273,13 @@ struct node_baton_t
/* Pointers to dumpfile data. */
svn_stringbuf_t *header;
svn_stringbuf_t *props;
+
+ /* Expect deltas? */
+ svn_boolean_t has_prop_delta;
+ svn_boolean_t has_text_delta;
+
+ /* We might need the node path in a parse error message. */
+ char *node_path;
};
@@ -261,6 +291,10 @@ static svn_error_t *
magic_header_record(int version, void *parse_baton, apr_pool_t *pool)
{
struct parse_baton_t *pb = parse_baton;
+
+ if (version >= SVN_REPOS_DUMPFILE_FORMAT_VERSION_DELTAS)
+ pb->allow_deltas = TRUE;
+
SVN_ERR(svn_stream_printf(pb->out_stream, pool,
SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
version));
@@ -566,10 +600,13 @@ new_node_record(void **node_baton,
nb->has_props = FALSE;
nb->has_text = FALSE;
+ nb->has_prop_delta = FALSE;
+ nb->has_text_delta = FALSE;
nb->writing_begun = FALSE;
nb->tcl = tcl ? svn__atoui64(tcl) : 0;
nb->header = svn_stringbuf_create_empty(pool);
nb->props = svn_stringbuf_create_empty(pool);
+ nb->node_path = apr_pstrdup(pool, node_path);
/* Now we know for sure that we have a node that will not be
skipped, flush the revision if it has not already been done. */
@@ -582,6 +619,14 @@ new_node_record(void **node_baton,
const char *key = svn__apr_hash_index_key(hi);
const char *val = svn__apr_hash_index_val(hi);
+ if ((!strcmp(key, SVN_REPOS_DUMPFILE_PROP_DELTA))
+ && (!strcmp(val, "true")))
+ nb->has_prop_delta = TRUE;
+
+ if ((!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_DELTA))
+ && (!strcmp(val, "true")))
+ nb->has_text_delta = TRUE;
+
if ((!strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH))
|| (!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH)))
@@ -804,10 +849,12 @@ set_node_property(void *node_baton,
if (nb->do_skip)
return SVN_NO_ERROR;
- if (!nb->has_props)
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Delta property block detected - "
- "not supported by svndumpfilter"));
+ if (! (nb->has_props || nb->has_prop_delta))
+ return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
+ _("Delta property block detected, but deltas "
+ "are not enabled for node '%s' in original "
+ "revision %ld"),
+ nb->node_path, rb->rev_orig);
if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
@@ -817,6 +864,7 @@ set_node_property(void *node_baton,
value = filtered_mergeinfo;
}
+ nb->has_props = TRUE;
write_prop_to_stringbuf(nb->props, name, value);
return SVN_NO_ERROR;
@@ -824,6 +872,29 @@ set_node_property(void *node_baton,
static svn_error_t *
+delete_node_property(void *node_baton, const char *name)
+{
+ struct node_baton_t *nb = node_baton;
+ struct revision_baton_t *rb = nb->rb;
+
+ if (nb->do_skip)
+ return SVN_NO_ERROR;
+
+ if (!nb->has_prop_delta)
+ return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
+ _("Delta property block detected, but deltas "
+ "are not enabled for node '%s' in original"
+ "revision %ld"),
+ nb->node_path, rb->rev_orig);
+
+ nb->has_props = TRUE;
+ write_propdel_to_stringbuf(&(nb->props), name);
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
remove_node_props(void *node_baton)
{
struct node_baton_t *nb = node_baton;
@@ -899,7 +970,7 @@ svn_repos_parse_fns3_t filtering_vtable
new_node_record,
set_revision_property,
set_node_property,
- NULL,
+ delete_node_property,
remove_node_props,
set_fulltext,
NULL,
@@ -1045,6 +1116,7 @@ parse_baton_initialize(struct parse_bato
baton->renumber_history = apr_hash_make(pool);
baton->last_live_revision = SVN_INVALID_REVNUM;
baton->oldest_original_rev = SVN_INVALID_REVNUM;
+ baton->allow_deltas = FALSE;
*pb = baton;
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1353745&r1=1353744&r2=1353745&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests.py Mon Jun 25
21:07:37 2012
@@ -654,11 +654,28 @@ def accepts_deltas(sbox):
dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
'svndumpfilter_tests_data',
'simple_v3.dump')
- dumpfile = open(dumpfile_location).read()
+ dump_in = open(dumpfile_location).read()
- filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include",
+ dump_out, err = filter_and_return_output(dump_in, 0, "include",
"trunk", "--quiet")
- load_and_verify_dumpstream(sbox, [], [], None, False, filtered_out)
+
+ expected_revs = [
+ svntest.wc.State('', {
+ 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}),
+ 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"),
+ }),
+ svntest.wc.State('', {
+ 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}),
+ 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"),
+ }),
+ svntest.wc.State('', {
+ 'trunk' : svntest.wc.StateItem(props={'story': 'Yada yada yada...'}),
+ 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"),
+ }),
+ ]
+
+ load_and_verify_dumpstream(sbox, [], [], expected_revs, True, dump_out,
+ '--ignore-uuid')
Modified:
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=1353745&r1=1353744&r2=1353745&view=diff
==============================================================================
Files
subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
(original) and
subversion/trunk/subversion/tests/cmdline/svndumpfilter_tests_data/simple_v3.dump
Mon Jun 25 21:07:37 2012 differ