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/20 18:52:21 UTC
svn commit: r1653314 [18/20] - in /subversion/branches/move-tracking-2: ./
notes/ subversion/ subversion/bindings/swig/
subversion/bindings/swig/include/ subversion/bindings/swig/perl/native/
subversion/bindings/swig/perl/native/t/ subversion/bindings/...
Modified: subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c Tue Jan 20 17:52:18 2015
@@ -695,6 +695,10 @@ handle_text_conflict(svn_wc_conflict_res
b->path_prefix, desc->local_abspath,
scratch_pool)));
+ /* ### TODO This whole feature availability check is grossly outdated.
+ DIFF_ALLOWED needs either to be redefined or to go away.
+ */
+
/* Diffing can happen between base and merged, to show conflict
markers to the user (this is the typical 3-way merge
scenario), or if no base is available, we can show a diff
@@ -714,9 +718,15 @@ handle_text_conflict(svn_wc_conflict_res
*next_option++ = "p";
if (diff_allowed)
{
- *next_option++ = "df";
+ /* We need one more path for this feature. */
+ if (desc->my_abspath)
+ *next_option++ = "df";
+
*next_option++ = "e";
- *next_option++ = "m";
+
+ /* We need one more path for this feature. */
+ if (desc->my_abspath)
+ *next_option++ = "m";
if (knows_something)
*next_option++ = "r";
@@ -781,7 +791,8 @@ handle_text_conflict(svn_wc_conflict_res
}
else if (strcmp(opt->code, "df") == 0)
{
- if (! diff_allowed)
+ /* Re-check preconditions. */
+ if (! diff_allowed || desc->my_abspath)
{
SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
_("Invalid option; there's no "
@@ -805,6 +816,15 @@ handle_text_conflict(svn_wc_conflict_res
{
svn_error_t *err;
+ /* Re-check preconditions. */
+ if (! desc->my_abspath)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+ _("Invalid option; there's no "
+ "base path to merge.\n\n")));
+ continue;
+ }
+
err = svn_cl__merge_file_externally(desc->base_abspath,
desc->their_abspath,
desc->my_abspath,
Modified: subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c Tue Jan 20 17:52:18 2015
@@ -1271,7 +1271,7 @@ subcommand_freeze(apr_getopt_t *os, void
}
b.command = APR_ARRAY_IDX(args, 0, const char *);
- b.args = apr_palloc(pool, sizeof(char *) * args->nelts + 1);
+ b.args = apr_palloc(pool, sizeof(char *) * (args->nelts + 1));
for (i = 0; i < args->nelts; ++i)
b.args[i] = APR_ARRAY_IDX(args, i, const char *);
b.args[args->nelts] = NULL;
Modified: subversion/branches/move-tracking-2/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svndumpfilter/svndumpfilter.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/move-tracking-2/subversion/svndumpfilter/svndumpfilter.c Tue Jan 20 17:52:18 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;
};
@@ -310,6 +310,24 @@ magic_header_record(int version, void *p
}
+/* Return a deep copy of a (char * -> char *) hash. */
+static apr_hash_t *
+headers_dup(apr_hash_t *headers,
+ apr_pool_t *pool)
+{
+ apr_hash_t *new_hash = apr_hash_make(pool);
+ apr_hash_index_t *hi;
+
+ 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);
+
+ svn_hash_sets(new_hash, apr_pstrdup(pool, key), apr_pstrdup(pool, val));
+ }
+ return new_hash;
+}
+
/* New revision: set up revision_baton, decide if we skip it. */
static svn_error_t *
new_revision_record(void **revision_baton,
@@ -318,21 +336,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 = headers_dup(headers, pool);
rev_orig = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER);
rb->rev_orig = SVN_STR_TO_REV(rev_orig);
@@ -342,28 +355,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 +366,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 +385,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 +393,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 +412,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
@@ -791,10 +746,16 @@ adjust_mergeinfo(svn_string_t **final_va
start of all history. E.g. if we dump -r100:400 then dumpfilter the
result with --skip-missing-merge-sources, any mergeinfo with revision
100 implies a change of -r99:100, but r99 is part of the history we
- want filtered. This is analogous to how r1 is always meaningless as
- a merge source revision.
+ want filtered.
If the oldest rev is r0 then there is nothing to filter. */
+
+ /* ### This seems to cater only for use cases where the revisions being
+ processed are not following on from revisions that will already
+ exist in the destination repository. If the revisions being
+ processed do follow on, then we might want to keep the mergeinfo
+ that refers to those older revisions. */
+
if (rb->pb->skip_missing_merge_sources && rb->pb->oldest_original_rev > 0)
SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
&mergeinfo, mergeinfo,
@@ -852,7 +813,7 @@ adjust_mergeinfo(svn_string_t **final_va
svn_hash_sets(final_mergeinfo, merge_source, rangelist);
}
- SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, 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);
@@ -868,7 +829,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));
@@ -887,6 +847,9 @@ set_node_property(void *node_baton,
if (nb->do_skip)
return SVN_NO_ERROR;
+ /* Try to detect if a delta-mode property occurs unexpectedly. HAS_PROPS
+ can be false here only if the parser didn't call remove_node_props(),
+ so this may indicate a bug rather than bad data. */
if (! (nb->has_props || nb->has_prop_delta))
return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
_("Delta property block detected, but deltas "
@@ -932,14 +895,17 @@ delete_node_property(void *node_baton, c
}
+/* The parser calls this method if the node record has a non-delta
+ * property content section, before any calls to set_node_property().
+ * If the node record uses property deltas, this is not called.
+ */
static svn_error_t *
remove_node_props(void *node_baton)
{
struct node_baton_t *nb = node_baton;
/* In this case, not actually indicating that the node *has* props,
- rather that we know about all the props that it has, since it now
- has none. */
+ rather that it has a property content section. */
nb->has_props = TRUE;
return SVN_NO_ERROR;
Modified: subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c Tue Jan 20 17:52:18 2015
@@ -31,6 +31,35 @@
#include "svn_private_config.h"
#include "svnfsfs.h"
+/* Return the string, allocated in RESULT_POOL, describing the value 2**I.
+ */
+static const char *
+print_two_power(int i,
+ apr_pool_t *result_pool)
+{
+ /* These are the SI prefixes for base-1000, the binary ones with base-1024
+ are too clumsy and require appending B for "byte" to be intelligible,
+ e.g. "MiB".
+
+ Therefore, we ignore the official standard and revert to the traditional
+ contextual use were the base-1000 prefixes are understood as base-1024
+ when it came to data sizes.
+ */
+ const char *si_prefixes = " kMGTPEZY";
+
+ int number = (1 << (i % 10));
+ int thousands = i / 10;
+
+ char si_prefix = ((thousands >= 0) && (thousands < strlen(si_prefixes)))
+ ? si_prefixes[thousands]
+ : '?';
+
+ if (si_prefix == ' ')
+ return apr_psprintf(result_pool, "%d", number);
+
+ return apr_psprintf(result_pool, "%d%c", number, si_prefix);
+}
+
/* Print statistics for the given group of representations to console.
* Use POOL for allocations.
*/
@@ -88,8 +117,8 @@ print_histogram(svn_fs_fs__histogram_t *
/* display histogram lines */
for (i = last; i >= first; --i)
- printf(_(" [2^%2d, 2^%2d) %15s (%2d%%) bytes in %12s (%2d%%) items\n"),
- i-1, i,
+ printf(_(" %4s .. < %-4s %19s (%2d%%) bytes in %12s (%2d%%) items\n"),
+ print_two_power(i-1, pool), print_two_power(i, pool),
svn__ui64toa_sep(histogram->lines[i].sum, ',', pool),
(int)(histogram->lines[i].sum * 100 / histogram->total.sum),
svn__ui64toa_sep(histogram->lines[i].count, ',', pool),
Modified: subversion/branches/move-tracking-2/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnrdump/dump_editor.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnrdump/dump_editor.c Tue Jan 20 17:52:18 2015
@@ -58,9 +58,6 @@ struct dir_baton
/* is this directory a new addition to this revision? */
svn_boolean_t added;
- /* has this directory been written to the output stream? */
- svn_boolean_t written_out;
-
/* the path to this directory */
const char *repos_relpath; /* a relpath */
@@ -179,38 +176,30 @@ make_dir_baton(const char *path,
struct dump_edit_baton *eb = edit_baton;
struct dir_baton *new_db = apr_pcalloc(pool, sizeof(*new_db));
const char *repos_relpath;
- apr_pool_t *dir_pool;
/* Construct the full path of this node. */
if (pb)
- {
- dir_pool = svn_pool_create(pb->pool);
- repos_relpath = svn_relpath_canonicalize(path, dir_pool);
- }
+ repos_relpath = svn_relpath_canonicalize(path, pool);
else
- {
- dir_pool = svn_pool_create(eb->pool);
- repos_relpath = "";
- }
+ repos_relpath = "";
/* Strip leading slash from copyfrom_path so that the path is
canonical and svn_relpath_join can be used */
if (copyfrom_path)
- copyfrom_path = svn_relpath_canonicalize(copyfrom_path, dir_pool);
+ copyfrom_path = svn_relpath_canonicalize(copyfrom_path, pool);
new_db->eb = eb;
new_db->parent_dir_baton = pb;
- new_db->pool = dir_pool;
+ new_db->pool = pool;
new_db->repos_relpath = repos_relpath;
new_db->copyfrom_path = copyfrom_path
- ? svn_relpath_canonicalize(copyfrom_path, dir_pool)
+ ? svn_relpath_canonicalize(copyfrom_path, pool)
: NULL;
new_db->copyfrom_rev = copyfrom_rev;
new_db->added = added;
- new_db->written_out = FALSE;
- new_db->props = apr_hash_make(dir_pool);
- new_db->deleted_props = apr_hash_make(dir_pool);
- new_db->deleted_entries = apr_hash_make(dir_pool);
+ new_db->props = apr_hash_make(pool);
+ new_db->deleted_props = apr_hash_make(pool);
+ new_db->deleted_entries = apr_hash_make(pool);
return new_db;
}
@@ -224,15 +213,14 @@ make_file_baton(const char *path,
struct dir_baton *pb,
apr_pool_t *pool)
{
- apr_pool_t *file_pool = svn_pool_create(pb->pool);
- struct file_baton *new_fb = apr_pcalloc(file_pool, sizeof(*new_fb));
+ struct file_baton *new_fb = apr_pcalloc(pool, sizeof(*new_fb));
new_fb->eb = pb->eb;
new_fb->parent_dir_baton = pb;
- new_fb->pool = file_pool;
- new_fb->repos_relpath = svn_relpath_canonicalize(path, file_pool);
- new_fb->props = apr_hash_make(file_pool);
- new_fb->deleted_props = apr_hash_make(file_pool);
+ new_fb->pool = pool;
+ new_fb->repos_relpath = svn_relpath_canonicalize(path, pool);
+ new_fb->props = apr_hash_make(pool);
+ new_fb->deleted_props = apr_hash_make(pool);
new_fb->is_copy = FALSE;
new_fb->copyfrom_path = NULL;
new_fb->copyfrom_rev = SVN_INVALID_REVNUM;
@@ -277,64 +265,6 @@ get_props_content(svn_stringbuf_t **head
return SVN_NO_ERROR;
}
-/* Extract and dump properties stored in PROPS and property deletions
- * stored in DELETED_PROPS. If TRIGGER_VAR is not NULL, it is set to
- * FALSE.
- *
- * If PROPSTRING is non-NULL, set *PROPSTRING to a string containing
- * the content block of the property changes; otherwise, dump that to
- * the stream, too.
- */
-static svn_error_t *
-do_dump_props(svn_stringbuf_t **propstring,
- svn_stream_t *stream,
- apr_hash_t *props,
- apr_hash_t *deleted_props,
- svn_boolean_t *trigger_var,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_stringbuf_t *header;
- svn_stringbuf_t *content;
- apr_size_t len;
-
- if (trigger_var && !*trigger_var)
- return SVN_NO_ERROR;
-
- SVN_ERR(get_props_content(&header, &content, props, deleted_props,
- result_pool, scratch_pool));
- len = header->len;
- SVN_ERR(svn_stream_write(stream, header->data, &len));
-
- if (propstring)
- {
- *propstring = content;
- }
- else
- {
- /* Content-length: 14 */
- SVN_ERR(svn_stream_printf(stream, scratch_pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n",
- content->len));
-
- len = content->len;
- SVN_ERR(svn_stream_write(stream, content->data, &len));
-
- /* No text is going to be dumped. Write a couple of newlines and
- wait for the next node/ revision. */
- SVN_ERR(svn_stream_puts(stream, "\n\n"));
-
- /* Cleanup so that data is never dumped twice. */
- apr_hash_clear(props);
- apr_hash_clear(deleted_props);
- if (trigger_var)
- *trigger_var = FALSE;
- }
-
- return SVN_NO_ERROR;
-}
-
static svn_error_t *
do_dump_newlines(struct dump_edit_baton *eb,
svn_boolean_t *trigger_var,
@@ -351,8 +281,7 @@ do_dump_newlines(struct dump_edit_baton
/*
* Write out a node record for PATH of type KIND under EB->FS_ROOT.
* ACTION describes what is happening to the node (see enum
- * svn_node_action). Write record to writable EB->STREAM, using
- * EB->BUFFER to write in chunks.
+ * svn_node_action). Write record to writable EB->STREAM.
*
* If the node was itself copied, IS_COPY is TRUE and the
* path/revision of the copy source are in COPYFROM_PATH/COPYFROM_REV.
@@ -411,10 +340,15 @@ dump_node(struct dump_edit_baton *eb,
case svn_node_action_replace:
if (is_copy)
{
- /* Delete the original, and then re-add the replacement as a
- copy using recursive calls into this function. */
- SVN_ERR(dump_node(eb, repos_relpath, db, fb, svn_node_action_delete,
- FALSE, NULL, SVN_INVALID_REVNUM, pool));
+ /* More complex case: is_copy is true, and copyfrom_path/
+ copyfrom_rev are present: delete the original, and then re-add
+ it */
+
+ SVN_ERR(svn_stream_puts(eb->stream,
+ SVN_REPOS_DUMPFILE_NODE_ACTION
+ ": delete\n\n"));
+
+ /* Recurse: Print an additional add-with-history record. */
SVN_ERR(dump_node(eb, repos_relpath, db, fb, svn_node_action_add,
is_copy, copyfrom_path, copyfrom_rev, pool));
}
@@ -547,31 +481,77 @@ static svn_error_t *
dump_pending(struct dump_edit_baton *eb,
apr_pool_t *scratch_pool)
{
+ svn_boolean_t dump_props = FALSE;
+ apr_hash_t *props, *deleted_props;
+
if (! eb->pending_baton)
return SVN_NO_ERROR;
+ /* Some pending properties to dump? */
if (eb->pending_kind == svn_node_dir)
{
struct dir_baton *db = eb->pending_baton;
- /* Some pending properties to dump? */
- SVN_ERR(do_dump_props(NULL, eb->stream, db->props, db->deleted_props,
- &(db->dump_props), db->pool, scratch_pool));
+ if (db->dump_props)
+ {
+ dump_props = TRUE;
+ props = db->props;
+ deleted_props = db->deleted_props;
- /* Some pending newlines to dump? */
- SVN_ERR(do_dump_newlines(eb, &(db->dump_newlines), scratch_pool));
+ db->dump_props = FALSE;
+ }
}
else if (eb->pending_kind == svn_node_file)
{
struct file_baton *fb = eb->pending_baton;
- /* Some pending properties to dump? */
- SVN_ERR(do_dump_props(NULL, eb->stream, fb->props, fb->deleted_props,
- &(fb->dump_props), fb->pool, scratch_pool));
+ if (fb->dump_props)
+ {
+ dump_props = TRUE;
+ props = fb->props;
+ deleted_props = fb->deleted_props;
+ fb->dump_props = FALSE;
+ }
}
else
abort();
+ if (dump_props)
+ {
+ svn_stringbuf_t *header, *content;
+ apr_size_t len;
+
+ SVN_ERR(get_props_content(&header, &content, props, deleted_props,
+ scratch_pool, scratch_pool));
+ len = header->len;
+ SVN_ERR(svn_stream_write(eb->stream, header->data, &len));
+
+ /* Content-length: 14 */
+ SVN_ERR(svn_stream_printf(eb->stream, scratch_pool,
+ SVN_REPOS_DUMPFILE_CONTENT_LENGTH
+ ": %" APR_SIZE_T_FMT "\n\n",
+ content->len));
+
+ len = content->len;
+ SVN_ERR(svn_stream_write(eb->stream, content->data, &len));
+
+ /* No text is going to be dumped. Write a couple of newlines and
+ wait for the next node/ revision. */
+ SVN_ERR(svn_stream_puts(eb->stream, "\n\n"));
+
+ /* Cleanup so that data is never dumped twice. */
+ apr_hash_clear(props);
+ apr_hash_clear(deleted_props);
+ }
+
+ if (eb->pending_kind == svn_node_dir)
+ {
+ struct dir_baton *db = eb->pending_baton;
+
+ /* Some pending newlines to dump? */
+ SVN_ERR(do_dump_newlines(eb, &(db->dump_newlines), scratch_pool));
+ }
+
/* Anything that was pending is pending no longer. */
eb->pending_baton = NULL;
eb->pending_kind = svn_node_none;
@@ -636,7 +616,6 @@ open_root(void *edit_baton,
/* Remember that we've started but not yet finished
handling this directory. */
- new_db->written_out = TRUE;
eb->pending_baton = new_db;
eb->pending_kind = svn_node_dir;
}
@@ -715,7 +694,6 @@ add_directory(const char *path,
/* Remember that we've started, but not yet finished handling this
directory. */
- new_db->written_out = TRUE;
pb->eb->pending_baton = new_db;
pb->eb->pending_kind = svn_node_dir;
@@ -801,7 +779,7 @@ close_directory(void *dir_baton,
}
/* ### should be unnecessary */
- svn_pool_destroy(db->pool);
+ apr_hash_clear(db->deleted_entries);
return SVN_NO_ERROR;
}
@@ -988,8 +966,16 @@ close_file(void *file_baton,
/* Some pending properties to dump? We'll dump just the headers for
now, then dump the actual propchange content only after dumping
the text headers too (if present). */
- SVN_ERR(do_dump_props(&propstring, eb->stream, fb->props, fb->deleted_props,
- &(fb->dump_props), pool, pool));
+ if (fb->dump_props)
+ {
+ svn_stringbuf_t *header;
+ apr_size_t len;
+
+ SVN_ERR(get_props_content(&header, &propstring, fb->props, fb->deleted_props,
+ pool, pool));
+ len = header->len;
+ SVN_ERR(svn_stream_write(eb->stream, header->data, &len));
+ }
/* Dump the text headers */
if (fb->dump_text)
@@ -1074,8 +1060,6 @@ close_file(void *file_baton,
dump` */
SVN_ERR(svn_stream_puts(eb->stream, "\n\n"));
- svn_pool_clear(fb->pool);
-
return SVN_NO_ERROR;
}
Modified: subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c Tue Jan 20 17:52:18 2015
@@ -66,9 +66,6 @@ struct parse_baton
/* To bleep, or not to bleep? (What kind of question is that?) */
svn_boolean_t quiet;
- /* UUID found in the dumpstream, if any; NULL otherwise. */
- const char *uuid;
-
/* Root URL of the target repository. */
const char *root_url;
@@ -99,13 +96,12 @@ struct parse_baton
/**
* Use to wrap the dir_context_t in commit.c so we can keep track of
- * depth, relpath and parent for open_directory and close_directory.
+ * relpath and parent for open_directory and close_directory.
*/
struct directory_baton
{
void *baton;
const char *relpath;
- int depth;
struct directory_baton *parent;
};
@@ -175,169 +171,6 @@ get_revision_mapping(apr_hash_t *rev_map
}
-/* Prepend the mergeinfo source paths in MERGEINFO_ORIG with
- PARENT_DIR, and return it in *MERGEINFO_VAL. */
-/* ### FIXME: Consider somehow sharing code with
- ### libsvn_repos/load-fs-vtable.c:prefix_mergeinfo_paths() */
-static svn_error_t *
-prefix_mergeinfo_paths(svn_string_t **mergeinfo_val,
- const svn_string_t *mergeinfo_orig,
- const char *parent_dir,
- apr_pool_t *pool)
-{
- apr_hash_t *prefixed_mergeinfo, *mergeinfo;
- apr_hash_index_t *hi;
- void *rangelist;
-
- SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_orig->data, pool));
- prefixed_mergeinfo = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
- {
- const void *key;
- const char *path, *merge_source;
-
- apr_hash_this(hi, &key, NULL, &rangelist);
- merge_source = svn_relpath_canonicalize(key, pool);
-
- /* The svn:mergeinfo property syntax demands a repos abspath */
- path = svn_fspath__canonicalize(svn_relpath_join(parent_dir,
- merge_source, pool),
- pool);
- svn_hash_sets(prefixed_mergeinfo, path, rangelist);
- }
- return svn_mergeinfo_to_string(mergeinfo_val, prefixed_mergeinfo, pool);
-}
-
-
-/* Examine the mergeinfo in INITIAL_VAL, renumber revisions in rangelists
- as appropriate, and return the (possibly new) mergeinfo in *FINAL_VAL
- (allocated from POOL). */
-/* ### FIXME: Consider somehow sharing code with
- ### libsvn_repos/load-fs-vtable.c:renumber_mergeinfo_revs() */
-static svn_error_t *
-renumber_mergeinfo_revs(svn_string_t **final_val,
- const svn_string_t *initial_val,
- struct revision_baton *rb,
- apr_pool_t *pool)
-{
- apr_pool_t *subpool = svn_pool_create(pool);
- svn_mergeinfo_t mergeinfo, predates_stream_mergeinfo;
- svn_mergeinfo_t final_mergeinfo = apr_hash_make(subpool);
- apr_hash_index_t *hi;
-
- SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));
-
- /* Issue #3020
- http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16
- Remove mergeinfo older than the oldest revision in the dump stream
- and adjust its revisions by the difference between the head rev of
- the target repository and the current dump stream rev. */
- if (rb->pb->oldest_dumpstream_rev > 1)
- {
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
- &predates_stream_mergeinfo, mergeinfo,
- rb->pb->oldest_dumpstream_rev - 1, 0,
- TRUE, subpool, subpool));
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
- &mergeinfo, mergeinfo,
- rb->pb->oldest_dumpstream_rev - 1, 0,
- FALSE, subpool, subpool));
- SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists(
- &predates_stream_mergeinfo,
- predates_stream_mergeinfo,
- -rb->rev_offset, subpool, subpool));
- }
- else
- {
- predates_stream_mergeinfo = NULL;
- }
-
- for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
- {
- svn_rangelist_t *rangelist;
- struct parse_baton *pb = rb->pb;
- int i;
- const void *path;
- apr_ssize_t pathlen;
- void *val;
-
- apr_hash_this(hi, &path, &pathlen, &val);
- rangelist = val;
-
- /* Possibly renumber revisions in merge source's rangelist. */
- for (i = 0; i < rangelist->nelts; i++)
- {
- svn_revnum_t rev_from_map;
- svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
- svn_merge_range_t *);
- rev_from_map = get_revision_mapping(pb->rev_map, range->start);
- if (SVN_IS_VALID_REVNUM(rev_from_map))
- {
- range->start = rev_from_map;
- }
- else if (range->start == pb->oldest_dumpstream_rev - 1)
- {
- /* Since the start revision of svn_merge_range_t are not
- inclusive there is one possible valid start revision that
- won't be found in the PB->REV_MAP mapping of load stream
- revsions to loaded revisions: The revision immediately
- preceding the oldest revision from the load stream.
- This is a valid revision for mergeinfo, but not a valid
- copy from revision (which PB->REV_MAP also maps for) so it
- will never be in the mapping.
-
- If that is what we have here, then find the mapping for the
- oldest rev from the load stream and subtract 1 to get the
- renumbered, non-inclusive, start revision. */
- rev_from_map = get_revision_mapping(pb->rev_map,
- pb->oldest_dumpstream_rev);
- if (SVN_IS_VALID_REVNUM(rev_from_map))
- range->start = rev_from_map - 1;
- }
- else
- {
- /* If we can't remap the start revision then don't even bother
- trying to remap the end revision. It's possible we might
- actually succeed at the latter, which can result in invalid
- mergeinfo with a start rev > end rev. If that gets into the
- repository then a world of bustage breaks loose anytime that
- bogus mergeinfo is parsed. See
- http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
- */
- continue;
- }
-
- rev_from_map = get_revision_mapping(pb->rev_map, range->end);
- if (SVN_IS_VALID_REVNUM(rev_from_map))
- range->end = rev_from_map;
- }
- apr_hash_set(final_mergeinfo, path, pathlen, rangelist);
- }
-
- if (predates_stream_mergeinfo)
- {
- 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_to_string(final_val, final_mergeinfo, pool));
- svn_pool_destroy(subpool);
-
- return SVN_NO_ERROR;
-}
-
-
static svn_error_t *
commit_callback(const svn_commit_info_t *commit_info,
void *baton,
@@ -599,9 +432,6 @@ uuid_record(const char *uuid,
void *parse_baton,
apr_pool_t *pool)
{
- struct parse_baton *pb;
- pb = parse_baton;
- pb->uuid = apr_pstrdup(pool, uuid);
return SVN_NO_ERROR;
}
@@ -661,7 +491,6 @@ new_node_record(void **node_baton,
/* child_db corresponds to the root directory baton here */
child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
child_db->baton = child_baton;
- child_db->depth = 0;
child_db->relpath = "";
child_db->parent = NULL;
rb->db = child_db;
@@ -745,7 +574,6 @@ new_node_record(void **node_baton,
LDR_DBG(("Opened dir %p\n", child_baton));
child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
child_db->baton = child_baton;
- child_db->depth = rb->db->depth + 1;
child_db->relpath = relpath_compose;
child_db->parent = rb->db;
rb->db = child_db;
@@ -813,7 +641,6 @@ new_node_record(void **node_baton,
nb->path, rb->db->baton, child_baton));
child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
child_db->baton = child_baton;
- child_db->depth = rb->db->depth + 1;
child_db->relpath = apr_pstrdup(rb->pool, nb->path);
child_db->parent = rb->db;
rb->db = child_db;
@@ -836,7 +663,6 @@ new_node_record(void **node_baton,
rb->pool, &child_baton));
child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
child_db->baton = child_baton;
- child_db->depth = rb->db->depth + 1;
child_db->relpath = apr_pstrdup(rb->pool, nb->path);
child_db->parent = rb->db;
rb->db = child_db;
@@ -893,51 +719,30 @@ set_node_property(void *baton,
const svn_string_t *value)
{
struct node_baton *nb = baton;
+ struct revision_baton *rb = nb->rb;
+ struct parse_baton *pb = rb->pb;
const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
apr_pool_t *pool = nb->rb->pool;
if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
- svn_string_t *renumbered_mergeinfo;
- svn_string_t prop_val;
+ svn_string_t *new_value;
+ svn_error_t *err;
- /* 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(value->data, "\r"))
+ err = svn_repos__adjust_mergeinfo_property(&new_value, value,
+ pb->parent_dir,
+ pb->rev_map,
+ pb->oldest_dumpstream_rev,
+ rb->rev_offset,
+ NULL, NULL, /*notify*/
+ pool, pool);
+ if (err)
{
- const char *prop_eol_normalized;
-
- SVN_ERR(svn_subst_translate_cstring2(value->data,
- &prop_eol_normalized,
- "\n", /* translate to LF */
- FALSE, /* no repair */
- NULL, /* no keywords */
- FALSE, /* no expansion */
- pool));
- prop_val.data = prop_eol_normalized;
- prop_val.len = strlen(prop_eol_normalized);
- value = &prop_val;
-
- /* ### TODO: notify? */
+ return svn_error_quick_wrap(err,
+ _("Invalid svn:mergeinfo value"));
}
- /* Renumber mergeinfo as appropriate. */
- SVN_ERR(renumber_mergeinfo_revs(&renumbered_mergeinfo, value,
- nb->rb, pool));
- value = renumbered_mergeinfo;
-
- if (nb->rb->pb->parent_dir)
- {
- /* 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,
- nb->rb->pb->parent_dir, pool));
- value = mergeinfo_val;
- }
+ value = new_value;
}
SVN_ERR(svn_rdump__normalize_prop(name, &value, pool));
Modified: subversion/branches/move-tracking-2/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnrdump/svnrdump.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnrdump/svnrdump.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnrdump/svnrdump.c Tue Jan 20 17:52:18 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,38 +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 *stdout_stream;
- svn_stream_t *revprop_stream;
-
- SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
- /* Revision-number: 19 */
- SVN_ERR(svn_stream_printf(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(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n", propstring->len));
-
- /* Content-length: 29 */
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n", propstring->len));
-
- /* Property data. */
- SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
- &(propstring->len)));
-
- SVN_ERR(svn_stream_puts(stdout_stream, "\n"));
- SVN_ERR(svn_stream_close(stdout_stream));
+ 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,
@@ -303,38 +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 *stdout_stream;
- svn_stream_t *revprop_stream;
- SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
-
- /* Revision-number: 19 */
- SVN_ERR(svn_stream_printf(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(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n", propstring->len));
-
- /* Content-length: 29 */
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
- SVN_REPOS_DUMPFILE_CONTENT_LENGTH
- ": %" APR_SIZE_T_FMT "\n\n", propstring->len));
-
- /* Property data. */
- SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
- &(propstring->len)));
-
- SVN_ERR(svn_stream_puts(stdout_stream, "\n"));
- SVN_ERR(svn_stream_close(stdout_stream));
+ 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,
@@ -471,35 +422,12 @@ 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;
}
@@ -1176,7 +1104,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
Modified: subversion/branches/move-tracking-2/subversion/svnserve/logger.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/logger.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/logger.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/logger.c Tue Jan 20 17:52:18 2015
@@ -134,7 +134,10 @@ logger__log_error(logger_t *logger,
if (len > sizeof(errstr) - sizeof(APR_EOL_STR)) {
len = sizeof(errstr) - sizeof(APR_EOL_STR);
}
+
memcpy(errstr + len, APR_EOL_STR, sizeof(APR_EOL_STR));
+ len += sizeof(APR_EOL_STR) -1; /* add NL, ex terminating NUL */
+
svn_error_clear(svn_stream_write(logger->stream, errstr, &len));
continuation = "-";
Modified: subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c Tue Jan 20 17:52:18 2015
@@ -271,6 +271,8 @@ static const apr_getopt_option_t svnserv
" "
"Default is 16.\n"
" "
+ "0 switches to dynamically sized caches.\n"
+ " "
"[used for FSFS and FSX repositories only]")},
{"cache-txdeltas", SVNSERVE_OPT_CACHE_TXDELTAS, 1,
N_("enable or disable caching of deltas between older\n"
Modified: subversion/branches/move-tracking-2/subversion/svnsync/svnsync.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnsync/svnsync.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnsync/svnsync.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnsync/svnsync.c Tue Jan 20 17:52:18 2015
@@ -764,8 +764,10 @@ open_target_session(svn_ra_session_t **t
/*** `svnsync init' ***/
/* Initialize the repository associated with RA session TO_SESSION,
- * using information found in BATON, while the repository is
- * locked. Implements `with_locked_func_t' interface.
+ * using information found in BATON.
+ *
+ * Implements `with_locked_func_t' interface. The caller has
+ * acquired a lock on the repository if locking is needed.
*/
static svn_error_t *
do_initialize(svn_ra_session_t *to_session,
@@ -1403,8 +1405,10 @@ replay_rev_finished(svn_revnum_t revisio
}
/* Synchronize the repository associated with RA session TO_SESSION,
- * using information found in BATON, while the repository is
- * locked. Implements `with_locked_func_t' interface.
+ * using information found in BATON.
+ *
+ * Implements `with_locked_func_t' interface. The caller has
+ * acquired a lock on the repository if locking is needed.
*/
static svn_error_t *
do_synchronize(svn_ra_session_t *to_session,
@@ -1597,8 +1601,10 @@ synchronize_cmd(apr_getopt_t *os, void *
/*** `svnsync copy-revprops' ***/
/* Copy revision properties to the repository associated with RA
- * session TO_SESSION, using information found in BATON, while the
- * repository is locked. Implements `with_locked_func_t' interface.
+ * session TO_SESSION, using information found in BATON.
+ *
+ * Implements `with_locked_func_t' interface. The caller has
+ * acquired a lock on the repository if locking is needed.
*/
static svn_error_t *
do_copy_revprops(svn_ra_session_t *to_session,
Modified: subversion/branches/move-tracking-2/subversion/svnsync/sync.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnsync/sync.c?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnsync/sync.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnsync/sync.c Tue Jan 20 17:52:18 2015
@@ -34,6 +34,8 @@
#include "svn_subst.h"
#include "svn_string.h"
+#include "private/svn_string_private.h"
+
#include "sync.h"
#include "svn_private_config.h"
@@ -83,6 +85,90 @@ normalize_string(const svn_string_t **st
return SVN_NO_ERROR;
}
+/* Remove r0 references from the mergeinfo string *STR.
+ *
+ * r0 was never a valid mergeinfo reference and cannot be committed with
+ * recent servers, but can be committed through a server older than 1.6.18
+ * for HTTP or older than 1.6.17 for the other protocols. See issue #4476
+ * "Mergeinfo containing r0 makes svnsync and dump and load fail".
+ *
+ * Set *WAS_CHANGED to TRUE if *STR was changed, otherwise to FALSE.
+ */
+static svn_error_t *
+remove_r0_mergeinfo(const svn_string_t **str,
+ svn_boolean_t *was_changed,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_stringbuf_t *new_str = svn_stringbuf_create_empty(result_pool);
+ apr_array_header_t *lines;
+ int i;
+
+ SVN_ERR_ASSERT(*str && (*str)->data);
+
+ *was_changed = FALSE;
+
+ /* for each line */
+ lines = svn_cstring_split((*str)->data, "\n", FALSE, scratch_pool);
+
+ for (i = 0; i < lines->nelts; i++)
+ {
+ char *line = APR_ARRAY_IDX(lines, i, char *);
+ char *colon;
+
+ /* split at the last colon */
+ colon = strrchr(line, ':');
+
+ if (! colon)
+ return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
+ _("Missing colon in svn:mergeinfo "
+ "property"));
+
+ /* remove r0 */
+ if (colon[1] == '0')
+ {
+ char *rangelist;
+
+ rangelist = colon + 1;
+
+ if (strncmp(rangelist, "0*,", 3) == 0)
+ {
+ rangelist += 3;
+ }
+ else if (strcmp(rangelist, "0*") == 0
+ || strncmp(rangelist, "0,", 2) == 0
+ || strncmp(rangelist, "0-1*", 4) == 0
+ || strncmp(rangelist, "0-1,", 4) == 0
+ || strcmp(rangelist, "0-1") == 0)
+ {
+ rangelist += 2;
+ }
+ else if (strcmp(rangelist, "0") == 0)
+ {
+ rangelist += 1;
+ }
+ else if (strncmp(rangelist, "0-", 2) == 0)
+ {
+ rangelist[0] = '1';
+ }
+
+ /* reassemble */
+ if (new_str->len)
+ svn_stringbuf_appendbyte(new_str, '\n');
+ svn_stringbuf_appendbytes(new_str, line, colon + 1 - line);
+ svn_stringbuf_appendcstr(new_str, rangelist);
+ }
+ }
+
+ if (strcmp((*str)->data, new_str->data) != 0)
+ {
+ *was_changed = TRUE;
+ }
+
+ *str = svn_stringbuf__morph_into_string(new_str);
+ return SVN_NO_ERROR;
+}
+
/* Normalize the encoding and line ending style of the values of properties
* in REV_PROPS that "need translation" (according to
@@ -153,6 +239,7 @@ typedef struct edit_baton_t {
svn_boolean_t got_textdeltas;
svn_revnum_t base_revision;
svn_boolean_t quiet;
+ svn_boolean_t mergeinfo_tweaked; /* Did we tweak svn:mergeinfo? */
svn_boolean_t strip_mergeinfo; /* Are we stripping svn:mergeinfo? */
svn_boolean_t migrate_svnmerge; /* Are we converting svnmerge.py data? */
svn_boolean_t mergeinfo_stripped; /* Did we strip svn:mergeinfo? */
@@ -414,8 +501,19 @@ change_file_prop(void *file_baton,
if (svn_prop_needs_translation(name))
{
svn_boolean_t was_normalized;
+ svn_boolean_t mergeinfo_tweaked = FALSE;
+
+ /* Normalize encoding to UTF-8, and EOL style to LF. */
SVN_ERR(normalize_string(&value, &was_normalized,
eb->source_prop_encoding, pool, pool));
+ /* Correct malformed mergeinfo. */
+ if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
+ {
+ SVN_ERR(remove_r0_mergeinfo(&value, &mergeinfo_tweaked,
+ pool, pool));
+ if (mergeinfo_tweaked)
+ eb->mergeinfo_tweaked = TRUE;
+ }
if (was_normalized)
(*(eb->normalized_node_props_counter))++;
}
@@ -513,8 +611,19 @@ change_dir_prop(void *dir_baton,
if (svn_prop_needs_translation(name))
{
svn_boolean_t was_normalized;
+ svn_boolean_t mergeinfo_tweaked = FALSE;
+
+ /* Normalize encoding to UTF-8, and EOL style to LF. */
SVN_ERR(normalize_string(&value, &was_normalized, eb->source_prop_encoding,
pool, pool));
+ /* Maybe adjust svn:mergeinfo. */
+ if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
+ {
+ SVN_ERR(remove_r0_mergeinfo(&value, &mergeinfo_tweaked,
+ pool, pool));
+ if (mergeinfo_tweaked)
+ eb->mergeinfo_tweaked = TRUE;
+ }
if (was_normalized)
(*(eb->normalized_node_props_counter))++;
}
@@ -548,6 +657,10 @@ close_edit(void *edit_baton,
{
if (eb->got_textdeltas)
SVN_ERR(svn_cmdline_printf(pool, "\n"));
+ if (eb->mergeinfo_tweaked)
+ SVN_ERR(svn_cmdline_printf(pool,
+ "NOTE: Adjusted Subversion mergeinfo in "
+ "this revision.\n"));
if (eb->mergeinfo_stripped)
SVN_ERR(svn_cmdline_printf(pool,
"NOTE: Dropped Subversion mergeinfo "
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py Tue Jan 20 17:52:18 2015
@@ -3146,6 +3146,31 @@ def basic_youngest(sbox):
'youngest', path)
+# With 'svn mkdir --parents' the target directory may already exist on disk.
+# In that case it was wrongly performing a recursive 'add' on its contents.
+def mkdir_parents_target_exists_on_disk(sbox):
+ "mkdir parents target exists on disk"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ Y_path = sbox.ospath('Y')
+ Y_Z_path = sbox.ospath('Y/Z')
+
+ os.mkdir(Y_path)
+ os.mkdir(Y_Z_path)
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'mkdir', '--parents', Y_path)
+
+ # Y should be added, and Z should not. There was a regression in which Z
+ # was also added.
+ expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+ expected_status.add({
+ 'Y' : Item(status='A ', wc_rev=0),
+ })
+ svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+
########################################################################
# Run the tests
@@ -3215,6 +3240,7 @@ test_list = [ None,
delete_conflicts_one_of_many,
peg_rev_on_non_existent_wc_path,
basic_youngest,
+ mkdir_parents_target_exists_on_disk,
]
if __name__ == '__main__':
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py Tue Jan 20 17:52:18 2015
@@ -560,7 +560,7 @@ def no_copy_overwrites(sbox):
# Repeat the last command. It should *fail* because A/D/H/G already exists.
svntest.actions.run_and_verify_svn(
"Whoa, I was able to overwrite a directory!",
- None, svntest.verify.AnyOutput,
+ None, ".*'/A/D/H/G'.*",
'cp', dirURL1, dirURL2,
'-m', 'fooogle')
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py Tue Jan 20 17:52:18 2015
@@ -3480,6 +3480,73 @@ def switch_relative_externals(sbox):
'up', wc)
+def copy_file_external_to_repo(sbox):
+ "explicitly copy file external to repo"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ change_external(sbox.ospath('A'), '^/A/mu ext')
+ sbox.simple_update()
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'cp',
+ '--message', 'external copy',
+ sbox.ospath('A/ext'),
+ sbox.repo_url + '/ext_copy')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'ext_copy' : Item(status='A '),
+ })
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.add({
+ 'A/ext' : Item('This is the file \'mu\'.\n'),
+ 'ext_copy' : Item('This is the file \'mu\'.\n'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output, expected_disk, None)
+
+@Issue(4550)
+def replace_tree_with_foreign_external(sbox):
+ "replace tree with foreign external"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ repo_dir = sbox.repo_dir
+
+ other_repo_dir, other_repo_url = sbox.add_repo_path('other')
+ svntest.main.copy_repos(repo_dir, other_repo_dir, 1)
+
+ sbox.simple_propset('svn:externals', other_repo_url + '/A/B X', 'A')
+ sbox.simple_commit()
+ sbox.simple_propdel('svn:externals', 'A')
+ sbox.simple_mkdir('A/X')
+ sbox.simple_mkdir('A/X/E')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/X' : Item(status='D '),
+ 'A' : Item(status=' U'),
+ 'A/X/lambda' : Item(status='A '),
+ 'A/X/E' : Item(status='A '),
+ 'A/X/E/alpha' : Item(status='A '),
+ 'A/X/E/beta' : Item(status='A '),
+ 'A/X/F' : Item(status='A '),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.add({
+ 'A/X' : Item(status=' ', wc_rev=1, prev_status='X '),
+ 'A/X/E' : Item(status=' ', wc_rev=1, prev_status=' '),
+ 'A/X/E/alpha' : Item(status=' ', wc_rev=1),
+ 'A/X/E/beta' : Item(status=' ', wc_rev=1),
+ 'A/X/F' : Item(status=' ', wc_rev=1),
+ 'A/X/lambda' : Item(status=' ', wc_rev=1),
+ })
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output, None, expected_status,
+ None, None, None, None, None, 1,
+ '-r', '2', wc_dir)
+
########################################################################
# Run the tests
@@ -3538,6 +3605,8 @@ test_list = [ None,
update_external_peg_rev,
update_deletes_file_external,
switch_relative_externals,
+ copy_file_external_to_repo,
+ replace_tree_with_foreign_external,
]
if __name__ == '__main__':
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py?rev=1653314&r1=1653313&r2=1653314&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py Tue Jan 20 17:52:18 2015
@@ -2355,6 +2355,26 @@ def lock_commit_bump(sbox):
svntest.actions.run_and_verify_info(expected_infos,
sbox.ospath('iota'))
+def copy_dir_with_locked_file(sbox):
+ "copy a directory containing a locked file"
+
+ sbox.build()
+ AA_url = sbox.repo_url + '/AA'
+ AA2_url = sbox.repo_url + '/AA2'
+ A_url = sbox.repo_url + '/A'
+ mu_url = A_url + '/mu'
+
+ svntest.main.run_svn(None, 'lock', '-m', 'locked', mu_url)
+
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'cp', A_url, AA_url,
+ '-m', '')
+
+ expected_err = "svn: E160037: .*no matching lock-token available"
+ svntest.actions.run_and_verify_svn(None, None, expected_err,
+ 'mv', A_url, AA2_url,
+ '-m', '')
+
########################################################################
# Run the tests
@@ -2420,6 +2440,7 @@ test_list = [ None,
dav_lock_refresh,
delete_locked_file_with_percent,
lock_commit_bump,
+ copy_dir_with_locked_file,
]
if __name__ == '__main__':