You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/01/19 13:37:30 UTC
svn commit: r1652987 - in /subversion/trunk/subversion:
include/private/svn_repos_private.h libsvn_repos/dump.c
svndumpfilter/svndumpfilter.c svnrdump/svnrdump.c
Author: julianfoad
Date: Mon Jan 19 12:37:29 2015
New Revision: 1652987
URL: http://svn.apache.org/r1652987
Log:
Factor out writing a dumpfile revision record from 'svnadmin load' and
'svnrdump load' and 'svndumpfilter'.
No functional change.
* subversion/private/svn_repos_private.h
(svn_repos__dump_revision_record): New function.
* subversion/libsvn_repos/dump.c
(write_header,
write_revision_headers,
svn_repos__dump_revision_record): New.
(write_revision_record): Don't serialize the headers and props here, just
pass them to svn_repos__dump_revision_record().
* subversion/svndumpfilter/svndumpfilter.c
(revision_baton_t): Store the original headers in the baton. Remove an
unneeded flag.
(new_revision_record): Don't filter and serialize the headers here, just
store them as a hash.
(output_revision): Don't serialize the headers and props here, just pass
them to svn_repos__dump_revision_record().
(set_revision_property): Remove initialization of the unneeded flag.
* subversion/svnrdump/svnrdump.c
(replay_revstart,
replay_revstart_v2,
dump_revision_header): Don't serialize the headers and props here, just
pass them to svn_repos__dump_revision_record().
Modified:
subversion/trunk/subversion/include/private/svn_repos_private.h
subversion/trunk/subversion/libsvn_repos/dump.c
subversion/trunk/subversion/svndumpfilter/svndumpfilter.c
subversion/trunk/subversion/svnrdump/svnrdump.c
Modified: subversion/trunk/subversion/include/private/svn_repos_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_repos_private.h?rev=1652987&r1=1652986&r2=1652987&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_repos_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_repos_private.h Mon Jan 19 12:37:29 2015
@@ -293,6 +293,31 @@ svn_repos__adjust_mergeinfo_property(svn
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Write a revision record to DUMP_STREAM for revision REVISION with revision
+ * properies REVPROPS, creating appropriate headers.
+ *
+ * Include all of the headers in EXTRA_HEADERS (if non-null), ignoring
+ * the revision number header and the three content length headers (which
+ * will be recreated as needed). EXTRA_HEADERS maps (char *) key to
+ * (char *) value.
+ *
+ * REVPROPS maps (char *) key to (svn_string_t *) value.
+ *
+ * Iff PROPS_SECTION_ALWAYS is true, include a prop content section (and
+ * corresponding header) even when REVPROPS is empty. This option exists
+ * to support a historical difference between svndumpfilter and svnadmin
+ * dump.
+ *
+ * Finally write another blank line.
+ */
+svn_error_t *
+svn_repos__dump_revision_record(svn_stream_t *dump_stream,
+ svn_revnum_t revision,
+ apr_hash_t *extra_headers,
+ apr_hash_t *revprops,
+ svn_boolean_t props_section_always,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/trunk/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/dump.c?rev=1652987&r1=1652986&r2=1652987&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/dump.c (original)
+++ subversion/trunk/subversion/libsvn_repos/dump.c Mon Jan 19 12:37:29 2015
@@ -38,6 +38,7 @@
#include "svn_props.h"
#include "svn_sorts.h"
+#include "private/svn_repos_private.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_fs_private.h"
#include "private/svn_sorts_private.h"
@@ -382,6 +383,125 @@ notify_warning(apr_pool_t *scratch_pool,
/*----------------------------------------------------------------------*/
+/* Write to STREAM the header in HEADERS named KEY, if present.
+ */
+static svn_error_t *
+write_header(svn_stream_t *stream,
+ apr_hash_t *headers,
+ const char *key,
+ apr_pool_t *scratch_pool)
+{
+ const char *val = svn_hash_gets(headers, key);
+
+ if (val)
+ {
+ SVN_ERR(svn_stream_printf(stream, scratch_pool,
+ "%s: %s\n", key, val));
+ }
+ return SVN_NO_ERROR;
+}
+
+/* Write headers, in arbitrary order.
+ * ### TODO: use a stable order
+ * ### Modifies HEADERS.
+ */
+static svn_error_t *
+write_revision_headers(svn_stream_t *stream,
+ apr_hash_t *headers,
+ apr_pool_t *scratch_pool)
+{
+ const char **h;
+ apr_hash_index_t *hi;
+
+ static const char *revision_headers_order[] =
+ {
+ SVN_REPOS_DUMPFILE_REVISION_NUMBER, /* must be first */
+ };
+
+ /* Write some headers in a given order */
+ for (h = revision_headers_order; *h; h++)
+ {
+ SVN_ERR(write_header(stream, headers, *h, scratch_pool));
+ svn_hash_sets(headers, *h, NULL);
+ }
+
+ /* Write any and all remaining headers except Content-length.
+ * ### TODO: use a stable order
+ */
+ for (hi = apr_hash_first(scratch_pool, headers); hi; hi = apr_hash_next(hi))
+ {
+ const char *key = apr_hash_this_key(hi);
+
+ if (strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH) != 0)
+ SVN_ERR(write_header(stream, headers, key, scratch_pool));
+ }
+
+ /* Content-length must be last */
+ SVN_ERR(write_header(stream, headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_repos__dump_revision_record(svn_stream_t *dump_stream,
+ svn_revnum_t revision,
+ apr_hash_t *extra_headers,
+ apr_hash_t *revprops,
+ svn_boolean_t props_section_always,
+ apr_pool_t *scratch_pool)
+{
+ svn_stringbuf_t *propstring = NULL;
+ apr_hash_t *headers;
+
+ if (extra_headers)
+ headers = apr_hash_copy(scratch_pool, extra_headers);
+ else
+ headers = apr_hash_make(scratch_pool);
+
+ /* ### someday write a revision-content-checksum */
+
+ svn_hash_sets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
+ apr_psprintf(scratch_pool, "%ld", revision));
+
+ if (apr_hash_count(revprops) || props_section_always)
+ {
+ svn_stream_t *propstream;
+
+ propstring = svn_stringbuf_create_empty(scratch_pool);
+ propstream = svn_stream_from_stringbuf(propstring, scratch_pool);
+ SVN_ERR(svn_hash_write2(revprops, propstream, "PROPS-END", scratch_pool));
+ SVN_ERR(svn_stream_close(propstream));
+
+ svn_hash_sets(headers, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH,
+ apr_psprintf(scratch_pool,
+ "%" APR_SIZE_T_FMT, propstring->len));
+ }
+
+ /* Write out a regular Content-length header for the benefit of
+ non-Subversion RFC-822 parsers. */
+ svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
+ apr_psprintf(scratch_pool,
+ "%" APR_SIZE_T_FMT, propstring->len));
+ SVN_ERR(write_revision_headers(dump_stream, headers, scratch_pool));
+
+ /* End of headers */
+ SVN_ERR(svn_stream_puts(dump_stream, "\n"));
+
+ /* Property data. */
+ if (propstring)
+ {
+ SVN_ERR(svn_stream_write(dump_stream, propstring->data, &propstring->len));
+ }
+
+ /* put an end to revision */
+ svn_stream_puts(dump_stream, "\n");
+
+ return SVN_NO_ERROR;
+}
+
+/*----------------------------------------------------------------------*/
+
/** An editor which dumps node-data in 'dumpfile format' to a file. **/
/* Look, mom! No file batons! */
@@ -1705,12 +1825,9 @@ write_revision_record(svn_stream_t *stre
svn_revnum_t rev,
apr_pool_t *pool)
{
- apr_size_t len;
apr_hash_t *props;
- svn_stringbuf_t *encoded_prophash;
apr_time_t timetemp;
svn_string_t *datevalue;
- svn_stream_t *propstream;
SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, pool));
@@ -1726,33 +1843,10 @@ write_revision_record(svn_stream_t *stre
svn_hash_sets(props, SVN_PROP_REVISION_DATE, datevalue);
}
- encoded_prophash = svn_stringbuf_create_ensure(0, pool);
- propstream = svn_stream_from_stringbuf(encoded_prophash, pool);
- SVN_ERR(svn_hash_write2(props, propstream, "PROPS-END", pool));
- SVN_ERR(svn_stream_close(propstream));
-
- /* ### someday write a revision-content-checksum */
-
- SVN_ERR(svn_stream_printf(stream, pool,
- SVN_REPOS_DUMPFILE_REVISION_NUMBER
- ": %ld\n", rev));
- SVN_ERR(svn_stream_printf(stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n",
- encoded_prophash->len));
-
- /* Write out a regular Content-length header for the benefit of
- non-Subversion RFC-822 parsers. */
- SVN_ERR(svn_stream_printf(stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n",
- encoded_prophash->len));
-
- len = encoded_prophash->len;
- SVN_ERR(svn_stream_write(stream, encoded_prophash->data, &len));
-
- len = 1;
- return svn_stream_write(stream, "\n", &len);
+ SVN_ERR(svn_repos__dump_revision_record(stream, rev, NULL, props,
+ TRUE /*props_section_always*/,
+ pool));
+ return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svndumpfilter/svndumpfilter.c?rev=1652987&r1=1652986&r2=1652987&view=diff
==============================================================================
--- subversion/trunk/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/trunk/subversion/svndumpfilter/svndumpfilter.c Mon Jan 19 12:37:29 2015
@@ -43,6 +43,7 @@
#include "svn_mergeinfo.h"
#include "svn_version.h"
+#include "private/svn_repos_private.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_cmdline_private.h"
#include "private/svn_sorts_private.h"
@@ -240,7 +241,6 @@ struct revision_baton_t
/* Does this revision have node or prop changes? */
svn_boolean_t has_nodes;
- svn_boolean_t has_props;
/* Did we drop any nodes? */
svn_boolean_t had_dropped_nodes;
@@ -253,7 +253,7 @@ struct revision_baton_t
svn_revnum_t rev_actual;
/* Pointers to dumpfile data. */
- svn_stringbuf_t *header;
+ apr_hash_t *original_headers;
apr_hash_t *props;
};
@@ -318,21 +318,16 @@ new_revision_record(void **revision_bato
apr_pool_t *pool)
{
struct revision_baton_t *rb;
- apr_hash_index_t *hi;
const char *rev_orig;
- svn_stream_t *header_stream;
*revision_baton = apr_palloc(pool, sizeof(struct revision_baton_t));
rb = *revision_baton;
rb->pb = parse_baton;
rb->has_nodes = FALSE;
- rb->has_props = FALSE;
rb->had_dropped_nodes = FALSE;
rb->writing_begun = FALSE;
- rb->header = svn_stringbuf_create_empty(pool);
rb->props = apr_hash_make(pool);
-
- header_stream = svn_stream_from_stringbuf(rb->header, pool);
+ rb->original_headers = apr_hash_copy(pool, headers);
rev_orig = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER);
rb->rev_orig = SVN_STR_TO_REV(rev_orig);
@@ -342,28 +337,6 @@ new_revision_record(void **revision_bato
else
rb->rev_actual = rb->rev_orig;
- SVN_ERR(svn_stream_printf(header_stream, pool,
- SVN_REPOS_DUMPFILE_REVISION_NUMBER ": %ld\n",
- rb->rev_actual));
-
- for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
- {
- const char *key = apr_hash_this_key(hi);
- const char *val = apr_hash_this_val(hi);
-
- if ((!strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH))
- || (!strcmp(key, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH))
- || (!strcmp(key, SVN_REPOS_DUMPFILE_REVISION_NUMBER)))
- continue;
-
- /* passthru: put header into header stringbuf. */
-
- SVN_ERR(svn_stream_printf(header_stream, pool, "%s: %s\n",
- key, val));
- }
-
- SVN_ERR(svn_stream_close(header_stream));
-
return SVN_NO_ERROR;
}
@@ -375,12 +348,8 @@ new_revision_record(void **revision_bato
static svn_error_t *
output_revision(struct revision_baton_t *rb)
{
- int bytes_used;
- char buf[SVN_KEYLINE_MAXLEN];
- apr_hash_index_t *hi;
svn_boolean_t write_out_rev = FALSE;
apr_pool_t *hash_pool = apr_hash_pool_get(rb->props);
- svn_stringbuf_t *props = svn_stringbuf_create_empty(hash_pool);
apr_pool_t *subpool = svn_pool_create(hash_pool);
rb->writing_begun = TRUE;
@@ -398,7 +367,6 @@ output_revision(struct revision_baton_t
&& (! rb->pb->drop_all_empty_revs))
{
apr_hash_t *old_props = rb->props;
- rb->has_props = TRUE;
rb->props = apr_hash_make(hash_pool);
svn_hash_sets(rb->props, SVN_PROP_REVISION_DATE,
svn_hash_gets(old_props, SVN_PROP_REVISION_DATE));
@@ -407,39 +375,6 @@ output_revision(struct revision_baton_t
"padding."), hash_pool));
}
- /* Now, "rasterize" the props to a string, and append the property
- information to the header string. */
- if (rb->has_props)
- {
- for (hi = apr_hash_first(subpool, rb->props);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *pname = apr_hash_this_key(hi);
- const svn_string_t *pval = apr_hash_this_val(hi);
-
- write_prop_to_stringbuf(props, pname, pval);
- }
- svn_stringbuf_appendcstr(props, "PROPS-END\n");
- svn_stringbuf_appendcstr(rb->header,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH);
- bytes_used = apr_snprintf(buf, sizeof(buf), ": %" APR_SIZE_T_FMT,
- props->len);
- svn_stringbuf_appendbytes(rb->header, buf, bytes_used);
- svn_stringbuf_appendbyte(rb->header, '\n');
- }
-
- svn_stringbuf_appendcstr(rb->header, SVN_REPOS_DUMPFILE_CONTENT_LENGTH);
- bytes_used = apr_snprintf(buf, sizeof(buf), ": %" APR_SIZE_T_FMT, props->len);
- svn_stringbuf_appendbytes(rb->header, buf, bytes_used);
- svn_stringbuf_appendbyte(rb->header, '\n');
-
- /* put an end to headers */
- svn_stringbuf_appendbyte(rb->header, '\n');
-
- /* put an end to revision */
- svn_stringbuf_appendbyte(props, '\n');
-
/* write out the revision */
/* Revision is written out in the following cases:
1. If the revision has nodes or
@@ -459,10 +394,12 @@ output_revision(struct revision_baton_t
if (write_out_rev)
{
/* This revision is a keeper. */
- SVN_ERR(svn_stream_write(rb->pb->out_stream,
- rb->header->data, &(rb->header->len)));
- SVN_ERR(svn_stream_write(rb->pb->out_stream,
- props->data, &(props->len)));
+ SVN_ERR(svn_repos__dump_revision_record(rb->pb->out_stream,
+ rb->rev_actual,
+ rb->original_headers,
+ rb->props,
+ FALSE /*props_section_always*/,
+ subpool));
/* Stash the oldest original rev not dropped. */
if (rb->rev_orig > 0
@@ -874,7 +811,6 @@ set_revision_property(void *revision_bat
struct revision_baton_t *rb = revision_baton;
apr_pool_t *hash_pool = apr_hash_pool_get(rb->props);
- rb->has_props = TRUE;
svn_hash_sets(rb->props,
apr_pstrdup(hash_pool, name),
svn_string_dup(value, hash_pool));
Modified: subversion/trunk/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/svnrdump.c?rev=1652987&r1=1652986&r2=1652987&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/svnrdump.c (original)
+++ subversion/trunk/subversion/svnrdump/svnrdump.c Mon Jan 19 12:37:29 2015
@@ -39,6 +39,7 @@
#include "svnrdump.h"
+#include "private/svn_repos_private.h"
#include "private/svn_cmdline_private.h"
#include "private/svn_ra_private.h"
@@ -229,34 +230,13 @@ replay_revstart(svn_revnum_t revision,
{
struct replay_baton *rb = replay_baton;
apr_hash_t *normal_props;
- svn_stringbuf_t *propstring;
- svn_stream_t *revprop_stream;
- /* Revision-number: 19 */
- SVN_ERR(svn_stream_printf(rb->stdout_stream, pool,
- SVN_REPOS_DUMPFILE_REVISION_NUMBER
- ": %ld\n", revision));
+ /* Normalize and dump the revprops */
SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool));
- propstring = svn_stringbuf_create_ensure(0, pool);
- revprop_stream = svn_stream_from_stringbuf(propstring, pool);
- SVN_ERR(svn_hash_write2(normal_props, revprop_stream, "PROPS-END", pool));
- SVN_ERR(svn_stream_close(revprop_stream));
-
- /* Prop-content-length: 13 */
- SVN_ERR(svn_stream_printf(rb->stdout_stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n", propstring->len));
-
- /* Content-length: 29 */
- SVN_ERR(svn_stream_printf(rb->stdout_stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n", propstring->len));
-
- /* Property data. */
- SVN_ERR(svn_stream_write(rb->stdout_stream, propstring->data,
- &(propstring->len)));
-
- SVN_ERR(svn_stream_puts(rb->stdout_stream, "\n"));
+ SVN_ERR(svn_repos__dump_revision_record(rb->stdout_stream, revision, NULL,
+ normal_props,
+ TRUE /*props_section_always*/,
+ pool));
SVN_ERR(svn_rdump__get_dump_editor(editor, edit_baton, revision,
rb->stdout_stream, rb->extra_ra_session,
@@ -299,34 +279,13 @@ replay_revstart_v2(svn_revnum_t revision
{
struct replay_baton *rb = replay_baton;
apr_hash_t *normal_props;
- svn_stringbuf_t *propstring;
- svn_stream_t *revprop_stream;
- /* Revision-number: 19 */
- SVN_ERR(svn_stream_printf(rb->stdout_stream, pool,
- SVN_REPOS_DUMPFILE_REVISION_NUMBER
- ": %ld\n", revision));
+ /* Normalize and dump the revprops */
SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool));
- propstring = svn_stringbuf_create_ensure(0, pool);
- revprop_stream = svn_stream_from_stringbuf(propstring, pool);
- SVN_ERR(svn_hash_write2(normal_props, revprop_stream, "PROPS-END", pool));
- SVN_ERR(svn_stream_close(revprop_stream));
-
- /* Prop-content-length: 13 */
- SVN_ERR(svn_stream_printf(rb->stdout_stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n", propstring->len));
-
- /* Content-length: 29 */
- SVN_ERR(svn_stream_printf(rb->stdout_stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n", propstring->len));
-
- /* Property data. */
- SVN_ERR(svn_stream_write(rb->stdout_stream, propstring->data,
- &(propstring->len)));
-
- SVN_ERR(svn_stream_puts(rb->stdout_stream, "\n"));
+ SVN_ERR(svn_repos__dump_revision_record(rb->stdout_stream, revision,
+ normal_props,
+ TRUE /*props_section_always*/,
+ pool));
SVN_ERR(svn_rdump__get_dump_editor_v2(editor, revision,
rb->stdout_stream,
@@ -463,35 +422,13 @@ dump_revision_header(svn_ra_session_t *s
apr_pool_t *pool)
{
apr_hash_t *prophash;
- svn_stringbuf_t *propstring;
- svn_stream_t *propstream;
-
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_REVISION_NUMBER
- ": %ld\n", revision));
prophash = apr_hash_make(pool);
- propstring = svn_stringbuf_create_empty(pool);
SVN_ERR(svn_ra_rev_proplist(session, revision, &prophash, pool));
-
- propstream = svn_stream_from_stringbuf(propstring, pool);
- SVN_ERR(svn_hash_write2(prophash, propstream, "PROPS-END", pool));
- SVN_ERR(svn_stream_close(propstream));
-
- /* Property-content-length: 14; Content-length: 14 */
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n",
- propstring->len));
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n",
- propstring->len));
- /* The properties */
- SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
- &(propstring->len)));
- SVN_ERR(svn_stream_puts(stdout_stream, "\n"));
-
+ SVN_ERR(svn_repos__dump_revision_record(stdout_stream, revision, NULL,
+ prophash,
+ TRUE /*props_section_always*/,
+ pool));
return SVN_NO_ERROR;
}
@@ -1168,7 +1105,7 @@ sub_main(int *exit_code, int argc, const
if (strcmp(subcommand->name, "load") == 0)
{
- /*
+ /*
* By default (no --*-interactive options given), the 'load' subcommand
* is interactive unless username and password were provided on the
* command line. This allows prompting for auth creds to work without