You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2015/01/16 15:01:37 UTC
svn commit: r1652409 [17/18] - in /subversion/branches/svn-auth-x509: ./
notes/ subversion/bindings/swig/ subversion/bindings/swig/include/
subversion/bindings/swig/perl/native/ subversion/bindings/swig/perl/native/t/
subversion/bindings/swig/python/li...
Modified: subversion/branches/svn-auth-x509/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svn/conflict-callbacks.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svn/conflict-callbacks.c Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svndumpfilter/svndumpfilter.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svndumpfilter/svndumpfilter.c Fri Jan 16 14:01:35 2015
@@ -791,10 +791,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 +858,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);
Modified: subversion/branches/svn-auth-x509/subversion/svnfsfs/stats-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnfsfs/stats-cmd.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnfsfs/stats-cmd.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnfsfs/stats-cmd.c Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnrdump/dump_editor.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnrdump/dump_editor.c Fri Jan 16 14:01:35 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;
@@ -351,8 +339,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.
@@ -636,7 +623,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 +701,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 +786,7 @@ close_directory(void *dir_baton,
}
/* ### should be unnecessary */
- svn_pool_destroy(db->pool);
+ apr_hash_clear(db->deleted_entries);
return SVN_NO_ERROR;
}
@@ -1074,8 +1059,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/svn-auth-x509/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnrdump/load_editor.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnrdump/load_editor.c Fri Jan 16 14:01:35 2015
@@ -320,16 +320,7 @@ renumber_mergeinfo_revs(svn_string_t **f
subpool, subpool));
}
- SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
-
- /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0
- or r1. However, svndumpfilter can be abused to produce r1 merge source
- revs. So if we encounter any, then strip them out, no need to put them
- into the load target. */
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&final_mergeinfo,
- final_mergeinfo,
- 1, 0, FALSE,
- subpool, subpool));
+ SVN_ERR(svn_mergeinfo__canonicalize_ranges(final_mergeinfo, subpool));
SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool));
svn_pool_destroy(subpool);
@@ -887,6 +878,56 @@ set_revision_property(void *baton,
return SVN_NO_ERROR;
}
+/* Adjust mergeinfo:
+ * - normalize line endings (if all CRLF, change to LF; but error if mixed);
+ * - adjust revision numbers (see renumber_mergeinfo_revs());
+ * - adjust paths (see prefix_mergeinfo_paths()).
+ */
+static svn_error_t *
+adjust_mergeinfo_property(struct revision_baton *rb,
+ svn_string_t **new_value_p,
+ const svn_string_t *old_value,
+ apr_pool_t *result_pool)
+{
+ struct parse_baton *pb = rb->pb;
+ svn_string_t prop_val = *old_value;
+
+ /* Tolerate mergeinfo with "\r\n" line endings because some
+ dumpstream sources might contain as much. If so normalize
+ the line endings to '\n' and notify that we have made this
+ correction. */
+ if (strstr(prop_val.data, "\r"))
+ {
+ const char *prop_eol_normalized;
+
+ SVN_ERR(svn_subst_translate_cstring2(prop_val.data,
+ &prop_eol_normalized,
+ "\n", /* translate to LF */
+ FALSE, /* no repair */
+ NULL, /* no keywords */
+ FALSE, /* no expansion */
+ result_pool));
+ prop_val.data = prop_eol_normalized;
+ prop_val.len = strlen(prop_eol_normalized);
+
+ /* ### TODO: notify? */
+ }
+
+ /* Renumber mergeinfo as appropriate. */
+ SVN_ERR(renumber_mergeinfo_revs(new_value_p, &prop_val, rb,
+ result_pool));
+
+ if (pb->parent_dir)
+ {
+ /* Prefix the merge source paths with PB->parent_dir. */
+ /* ASSUMPTION: All source paths are included in the dump stream. */
+ SVN_ERR(prefix_mergeinfo_paths(new_value_p, *new_value_p,
+ pb->parent_dir, result_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
set_node_property(void *baton,
const char *name,
@@ -898,46 +939,10 @@ set_node_property(void *baton,
if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
- svn_string_t *renumbered_mergeinfo;
- svn_string_t prop_val;
-
- /* 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"))
- {
- const char *prop_eol_normalized;
+ svn_string_t *new_value;
- 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? */
- }
-
- /* 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;
- }
+ SVN_ERR(adjust_mergeinfo_property(nb->rb, &new_value, value, pool));
+ value = new_value;
}
SVN_ERR(svn_rdump__normalize_prop(name, &value, pool));
Modified: subversion/branches/svn-auth-x509/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnrdump/svnrdump.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnrdump/svnrdump.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnrdump/svnrdump.c Fri Jan 16 14:01:35 2015
@@ -230,13 +230,10 @@ 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_ERR(svn_stream_printf(rb->stdout_stream, pool,
SVN_REPOS_DUMPFILE_REVISION_NUMBER
": %ld\n", revision));
SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool));
@@ -246,21 +243,20 @@ replay_revstart(svn_revnum_t revision,
SVN_ERR(svn_stream_close(revprop_stream));
/* Prop-content-length: 13 */
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
+ 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(stdout_stream, pool,
+ 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(stdout_stream, propstring->data,
+ SVN_ERR(svn_stream_write(rb->stdout_stream, propstring->data,
&(propstring->len)));
- SVN_ERR(svn_stream_puts(stdout_stream, "\n"));
- SVN_ERR(svn_stream_close(stdout_stream));
+ SVN_ERR(svn_stream_puts(rb->stdout_stream, "\n"));
SVN_ERR(svn_rdump__get_dump_editor(editor, edit_baton, revision,
rb->stdout_stream, rb->extra_ra_session,
@@ -304,13 +300,10 @@ 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_ERR(svn_stream_printf(rb->stdout_stream, pool,
SVN_REPOS_DUMPFILE_REVISION_NUMBER
": %ld\n", revision));
SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool));
@@ -320,21 +313,20 @@ replay_revstart_v2(svn_revnum_t revision
SVN_ERR(svn_stream_close(revprop_stream));
/* Prop-content-length: 13 */
- SVN_ERR(svn_stream_printf(stdout_stream, pool,
+ 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(stdout_stream, pool,
+ 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(stdout_stream, propstring->data,
+ SVN_ERR(svn_stream_write(rb->stdout_stream, propstring->data,
&(propstring->len)));
- SVN_ERR(svn_stream_puts(stdout_stream, "\n"));
- SVN_ERR(svn_stream_close(stdout_stream));
+ SVN_ERR(svn_stream_puts(rb->stdout_stream, "\n"));
SVN_ERR(svn_rdump__get_dump_editor_v2(editor, revision,
rb->stdout_stream,
Modified: subversion/branches/svn-auth-x509/subversion/svnserve/logger.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnserve/logger.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnserve/logger.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnserve/logger.c Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnserve/svnserve.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnserve/svnserve.c Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/svnsync/svnsync.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnsync/svnsync.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnsync/svnsync.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnsync/svnsync.c Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/svnsync/sync.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/svnsync/sync.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/svnsync/sync.c (original)
+++ subversion/branches/svn-auth-x509/subversion/svnsync/sync.c Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/basic_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/basic_tests.py Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/copy_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/copy_tests.py Fri Jan 16 14:01:35 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/svn-auth-x509/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/externals_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/externals_tests.py Fri Jan 16 14:01:35 2015
@@ -3121,7 +3121,7 @@ def move_with_file_externals(sbox):
sbox.simple_commit()
sbox.simple_update()
-@Issue(4185)
+@Issue(4185,4529)
def pinned_externals(sbox):
"pinned external"
@@ -3134,6 +3134,7 @@ def pinned_externals(sbox):
sbox.simple_mkdir('Z')
sbox.simple_commit('')
+ repo_X_C = repo_url + '/X/C'
repo_X_mu = repo_url + '/X/mu'
expected_output = verify.RegexOutput(
@@ -3153,20 +3154,18 @@ def pinned_externals(sbox):
'old-rev -r 1 ' + repo_X_mu + '\n' +
repo_X_mu + ' new-plain\n' +
'-r1 ' + repo_X_mu + ' new-rev\n' +
- repo_X_mu + '@1 new-peg\n',
+ repo_X_mu + '@1 new-peg\n'
+ '-r1 ' + repo_X_C + ' new-dir-rev\n',
'Z')
- expected_output = svntest.wc.State(wc_dir, {
- 'A/D' : Item(status=' U'),
- 'A/D/exdir_E/beta' : Item(status='A '),
- 'A/D/exdir_E/alpha' : Item(status='A '),
- })
expected_error = "svn: E205011: Failure.*externals"
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
# The interesting values
'Z/old-plain' : Item(contents="This is the file 'mu'.\n"),
'Z/new-plain' : Item(contents="This is the file 'mu'.\n"),
+ 'Z/new-rev' : Item(contents="This is the file 'mu'.\n"),
+ 'Z/new-dir-rev' : Item(),
# And verifying X
'X/D/H/psi' : Item(contents="This is the file 'psi'.\n"),
@@ -3481,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
@@ -3539,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/svn-auth-x509/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/lock_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/lock_tests.py Fri Jan 16 14:01:35 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__':
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/patch_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/patch_tests.py Fri Jan 16 14:01:35 2015
@@ -4689,6 +4689,396 @@ def patch_git_rename(sbox):
expected_output, expected_disk,
expected_status, expected_skip)
+@Issue(4533)
+def patch_hunk_avoid_reorder(sbox):
+ """avoid reordering hunks"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_append('A/mu',
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n', truncate=True)
+ sbox.simple_commit()
+
+ # two hunks, first matches at offset +18, second matches at both -13
+ # and +18 but we want the second match as it is after the first
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -13,6 +13,7 @@\n",
+ " MM\n",
+ " NN\n",
+ " OO\n",
+ "+11111\n",
+ " PP\n",
+ " QQ\n",
+ " RR\n",
+ "@@ -20,6 +20,7 @@\n",
+ " TT\n",
+ " UU\n",
+ " VV\n",
+ "+22222\n",
+ " WW\n",
+ " XX\n",
+ " YY\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+ '> applied hunk @@ -20,6 +20,7 @@ with offset 18\n'
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ sbox.simple_revert('A/mu')
+
+ # change patch so second hunk matches at both -14 and +17, we still
+ # want the second match
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -13,6 +13,7 @@\n",
+ " MM\n",
+ " NN\n",
+ " OO\n",
+ "+11111\n",
+ " PP\n",
+ " QQ\n",
+ " RR\n",
+ "@@ -21,6 +21,7 @@\n",
+ " TT\n",
+ " UU\n",
+ " VV\n",
+ "+22222\n",
+ " WW\n",
+ " XX\n",
+ " YY\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+ '> applied hunk @@ -21,6 +21,7 @@ with offset 17\n'
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ sbox.simple_revert('A/mu')
+
+@Issue(4533)
+def patch_hunk_avoid_reorder2(sbox):
+ """avoid reordering hunks 2"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_append('A/mu',
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n', truncate=True)
+ sbox.simple_commit()
+
+ # two hunks, first matches at offset +18, second matches at both -13
+ # change patch so second hunk matches at both -12 and +19, we still
+ # want the second match
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -13,6 +13,7 @@\n",
+ " MM\n",
+ " NN\n",
+ " OO\n",
+ "+11111\n",
+ " PP\n",
+ " QQ\n",
+ " RR\n",
+ "@@ -19,6 +19,7 @@\n",
+ " TT\n",
+ " UU\n",
+ " VV\n",
+ "+22222\n",
+ " WW\n",
+ " XX\n",
+ " YY\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+ '> applied hunk @@ -19,6 +19,7 @@ with offset 19\n'
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+@Issue(4533)
+def patch_hunk_reorder(sbox):
+ """hunks that reorder"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_append('A/mu',
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n' 'GG\n'
+ 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n' 'MM\n' 'NN\n',
+ truncate=True)
+ sbox.simple_commit()
+
+ # Two hunks match in opposite order
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -2,6 +2,7 @@\n",
+ " II\n",
+ " JJ\n",
+ " KK\n",
+ "+11111\n",
+ " LL\n",
+ " MM\n",
+ " NN\n",
+ "@@ -9,6 +10,7 @@\n",
+ " BB\n",
+ " CC\n",
+ " DD\n",
+ "+22222\n",
+ " EE\n",
+ " FF\n",
+ " GG\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -9,6 +10,7 @@ with offset -7\n',
+ '> applied hunk @@ -2,6 +2,7 @@ with offset 7\n',
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' '22222\n' 'EE\n' 'FF\n' 'GG\n'
+ 'HH\n' 'II\n' 'JJ\n' 'KK\n' '11111\n' 'LL\n' 'MM\n' 'NN\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+@XFail()
+def patch_hunk_overlap(sbox):
+ """hunks that overlap"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_append('A/mu',
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'GG\n' 'HH\n' 'II\n', truncate=True)
+ sbox.simple_commit()
+
+ # Two hunks that overlap when applied, GNU patch can apply both hunks.
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -2,6 +2,7 @@\n",
+ " BB\n",
+ " CC\n",
+ " DD\n",
+ "+11111\n",
+ " EE\n",
+ " FF\n",
+ " GG\n",
+ "@@ -9,6 +10,7 @@\n",
+ " DD\n",
+ " EE\n",
+ " FF\n",
+ "+22222\n",
+ " GG\n",
+ " HH\n",
+ " II\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -9,6 +10,7 @@ with offset -5\n',
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' '11111\n' 'EE\n' 'FF\n'
+ '22222\n' 'GG\n' 'HH\n' 'II\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+def patch_delete_modified(sbox):
+ """patch delete modified"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # A patch that deletes beta.
+ unidiff_patch = [
+ "Index: A/B/E/beta\n",
+ "===================================================================\n",
+ "--- A/B/E/beta (revision 1)\n",
+ "+++ A/B/E/beta (working copy)\n",
+ "@@ -1 +0,0 @@\n",
+ "-This is the file 'beta'.\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ # First application deletes beta
+ expected_output = [
+ 'D %s\n' % sbox.ospath('A/B/E/beta'),
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.remove('A/B/E/beta')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/B/E/beta', status='D ')
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ # Second application skips
+ expected_output = [
+ 'Skipped \'%s\'\n' % sbox.ospath('A/B/E/beta'),
+ ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+ expected_skip = wc.State('', {
+ sbox.ospath('A/B/E/beta') : Item(verb='Skipped'),
+ })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ # Third application, with file present even though state is 'D', also skips
+ sbox.simple_append('A/B/E/beta', 'Modified', truncate=True)
+ expected_disk.add({'A/B/E/beta' : Item(contents='Modified')})
+ expected_output = [
+ 'Skipped \'%s\'\n' % sbox.ospath('A/B/E/beta'),
+ ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+ expected_skip = wc.State('', {
+ sbox.ospath('A/B/E/beta') : Item(verb='Skipped'),
+ })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ # Revert and modify beta, fourth application gives a text conflict.
+ sbox.simple_revert('A/B/E/beta')
+ sbox.simple_append('A/B/E/beta', 'Modified', truncate=True)
+
+ expected_output = [
+ 'C %s\n' % sbox.ospath('A/B/E/beta'),
+ '> rejected hunk @@ -1,1 +0,0 @@\n',
+ ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+ expected_skip = wc.State('', { })
+ reject_file_contents = [
+ "--- A/B/E/beta\n",
+ "+++ A/B/E/beta\n",
+ "@@ -1,1 +0,0 @@\n",
+ "-This is the file 'beta'.\n",
+ ]
+ expected_disk.add({'A/B/E/beta.svnpatch.rej'
+ : Item(contents=''.join(reject_file_contents))
+ })
+ expected_status.tweak('A/B/E/beta', status='M ')
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
########################################################################
#Run the tests
@@ -4741,7 +5131,12 @@ test_list = [ None,
patch_apply_no_fuz,
patch_lacking_trailing_eol_on_context,
patch_with_custom_keywords,
- patch_git_rename
+ patch_git_rename,
+ patch_hunk_avoid_reorder,
+ patch_hunk_avoid_reorder2,
+ patch_hunk_reorder,
+ patch_hunk_overlap,
+ patch_delete_modified,
]
if __name__ == '__main__':
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/redirect_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/redirect_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/redirect_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/redirect_tests.py Fri Jan 16 14:01:35 2015
@@ -178,6 +178,33 @@ def redirected_nonroot_update(sbox):
verify_url(wc_dir, checkout_url)
#----------------------------------------------------------------------
+@SkipUnless(svntest.main.is_ra_type_dav)
+def redirected_externals(sbox):
+ "redirected externals"
+
+ sbox.build()
+
+ sbox.simple_propset('svn:externals',
+ '^/A/B/E/alpha fileX\n'
+ '^/A/B/F dirX',
+ 'A/C')
+ sbox.simple_commit()
+ sbox.simple_update()
+
+ wc_dir = sbox.add_wc_path("my")
+ co_url = sbox.redirected_root_url()
+ exit_code, out, err = svntest.main.run_svn(None, 'co', co_url, wc_dir)
+ if err:
+ raise svntest.Failure
+ if not redirect_regex.match(out[0]):
+ raise svntest.Failure
+
+ verify_url(wc_dir, sbox.repo_url)
+ verify_url(sbox.ospath('A/C/fileX'), sbox.repo_url + '/A/B/E/alpha',
+ wc_path_is_file=True)
+ verify_url(sbox.ospath('A/C/dirX'), sbox.repo_url + '/A/B/F')
+
+#----------------------------------------------------------------------
########################################################################
# Run the tests
@@ -188,6 +215,7 @@ test_list = [ None,
redirected_checkout,
redirected_update,
redirected_nonroot_update,
+ redirected_externals,
]
if __name__ == '__main__':
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnadmin_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnadmin_tests.py Fri Jan 16 14:01:35 2015
@@ -32,6 +32,7 @@ import shutil
import sys
import threading
import time
+import gzip
logger = logging.getLogger()
@@ -2938,6 +2939,35 @@ def upgrade(sbox):
'-m', svntest.main.make_log_msg(),
sbox.repo_url + '/dir')
+def load_txdelta(sbox):
+ "exercising svn_txdelta_target on BDB"
+
+ test_create(sbox)
+
+ # This dumpfile produced a BDB repository that generated cheksum
+ # mismatches on read caused by the improper handling of
+ # svn_txdelta_target ops. The bug was fixed by r1640832.
+
+ dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
+ 'svnadmin_tests_data',
+ 'load_txdelta.dump.gz')
+ dumpfile = gzip.open(dumpfile_location).read()
+
+ load_dumpstream(sbox, dumpfile)
+
+ # Verify would fail with a checksum mismatch:
+ # * Error verifying revision 14.
+ # svnadmin: E200014: MD5 checksum mismatch on representation 'r':
+ # expected: 5182e8876ed894dc7fe28f6ff5b2fee6
+ # actual: 5121f82875508863ad70daa8244e6947
+
+ exit_code, output, errput = svntest.main.run_svnadmin("verify", sbox.repo_dir)
+ if errput:
+ raise SVNUnexpectedStderr(errput)
+ if svntest.verify.verify_outputs(
+ "Output of 'svnadmin verify' is unexpected.", None, output, None,
+ ".*Verified revision *"):
+ raise svntest.Failure
########################################################################
# Run the tests
@@ -2992,6 +3022,7 @@ test_list = [ None,
fsfs_hotcopy_progress_old,
freeze_same_uuid,
upgrade,
+ load_txdelta,
]
if __name__ == '__main__':
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/svndumpfilter_tests.py Fri Jan 16 14:01:35 2015
@@ -60,15 +60,10 @@ def filter_and_return_output(dump, bufsi
dump = [ dump ]
# Does the caller want the stderr?
- try:
- varargs.index('-q')
+ if '-q' in varargs or '--quiet' in varargs:
expected_errput = None # Stderr with -q or --quiet is a real error!
- except:
- try:
- varargs.index('--quiet')
- expected_errput = None
- except:
- expected_errput = svntest.verify.AnyOutput
+ else:
+ expected_errput = svntest.verify.AnyOutput
## TODO: Should we handle exit_code?
exit_code, output, errput = svntest.main.run_command_stdin(
svntest.main.svndumpfilter_binary, expected_errput, bufsize, True,
@@ -323,9 +318,9 @@ def filter_mergeinfo_revs_outside_of_dum
# --skip-missing-merge-soruces which should strip out any revisions < 6.
# Then we'll load the filtered result into an empty repository. This
# should offset the incoming mergeinfo by -5. In addition, any mergeinfo
- # revisions that are adjusted to r1 should be removed because that implies
- # a merge of -r0:1, which is impossible. The resulting mergeinfo should
- # look like this:
+ # referring to the initial revision in the dump file (r6) should be
+ # removed because the change it refers to (r5:6) is not wholly within the
+ # dumpfile. The resulting mergeinfo should look like this:
#
# Properties on 'branches/B1':
# svn:mergeinfo
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnrdump_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnrdump_tests.py Fri Jan 16 14:01:35 2015
@@ -70,27 +70,28 @@ def build_repos(sbox):
# Create an empty repository.
svntest.main.create_repos(sbox.repo_dir)
-def compare_repos_dumps(svnrdump_sbox, svnadmin_dumpfile):
- """Compare two dumpfiles, one created from SVNRDUMP_SBOX, and other given
- by SVNADMIN_DUMPFILE. The dumpfiles do not need to match linewise, as the
- SVNADMIN_DUMPFILE contents will first be loaded into a repository and then
+def compare_repos_dumps(sbox, other_dumpfile,
+ bypass_prop_validation=False):
+ """Compare two dumpfiles, one created from SBOX, and other given
+ by OTHER_DUMPFILE. The dumpfiles do not need to match linewise, as the
+ OTHER_DUMPFILE contents will first be loaded into a repository and then
re-dumped to do the match, which should generate the same dumpfile as
- dumping SVNRDUMP_SBOX."""
+ dumping SBOX."""
- svnrdump_contents = svntest.actions.run_and_verify_dump(
- svnrdump_sbox.repo_dir)
- svnadmin_sbox = svnrdump_sbox.clone_dependent()
- svntest.main.safe_rmtree(svnadmin_sbox.repo_dir)
- svntest.main.create_repos(svnadmin_sbox.repo_dir)
+ sbox_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir)
- svntest.actions.run_and_verify_load(svnadmin_sbox.repo_dir, svnadmin_dumpfile)
-
- svnadmin_contents = svntest.actions.run_and_verify_dump(
- svnadmin_sbox.repo_dir)
+ # Load and dump the other dumpfile (using svnadmin)
+ other_sbox = sbox.clone_dependent()
+ svntest.main.safe_rmtree(other_sbox.repo_dir)
+ svntest.main.create_repos(other_sbox.repo_dir)
+ svntest.actions.run_and_verify_load(other_sbox.repo_dir, other_dumpfile,
+ bypass_prop_validation)
+ other_dumpfile = svntest.actions.run_and_verify_dump(other_sbox.repo_dir)
+ ### This call kind-of assumes EXPECTED is first and ACTUAL is second.
svntest.verify.compare_dump_files(
- "Dump files", "DUMP", svnadmin_contents, svnrdump_contents)
+ "Dump files", "DUMP", other_dumpfile, sbox_dumpfile)
def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None,
subdir = None, bypass_prop_validation = False,
@@ -111,11 +112,10 @@ def run_dump_test(sbox, dumpfile_name, e
# Load the specified dump file into the sbox repository using
# svnadmin load
- svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
+ original_dumpfile = open(os.path.join(svnrdump_tests_dir,
dumpfile_name),
'rb').readlines()
-
- svntest.actions.run_and_verify_load(sbox.repo_dir, svnadmin_dumpfile,
+ svntest.actions.run_and_verify_load(sbox.repo_dir, original_dumpfile,
bypass_prop_validation)
repo_url = sbox.repo_url
@@ -129,28 +129,29 @@ def run_dump_test(sbox, dumpfile_name, e
[], 0, *opts)
if expected_dumpfile_name:
- svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
+ expected_dumpfile = open(os.path.join(svnrdump_tests_dir,
expected_dumpfile_name),
'rb').readlines()
# Compare the output from stdout
if ignore_base_checksums:
- svnadmin_dumpfile = [l for l in svnadmin_dumpfile
+ expected_dumpfile = [l for l in expected_dumpfile
if not l.startswith('Text-delta-base-md5')]
svnrdump_dumpfile = [l for l in svnrdump_dumpfile
if not l.startswith('Text-delta-base-md5')]
- svnadmin_dumpfile = [l for l in svnadmin_dumpfile
+ expected_dumpfile = [l for l in expected_dumpfile
if not mismatched_headers_re.match(l)]
svnrdump_dumpfile = [l for l in svnrdump_dumpfile
if not mismatched_headers_re.match(l)]
- svnadmin_dumpfile = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
+ expected_dumpfile = svntest.verify.UnorderedOutput(expected_dumpfile)
svntest.verify.compare_and_display_lines(
- "Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
+ "Dump files", "DUMP", expected_dumpfile, svnrdump_dumpfile,
None)
else:
- compare_repos_dumps(sbox, svnadmin_dumpfile)
+ # The expected dumpfile is the result of dumping SBOX.
+ compare_repos_dumps(sbox, svnrdump_dumpfile, bypass_prop_validation)
def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None,
expect_deltas = True):
@@ -169,36 +170,37 @@ def run_load_test(sbox, dumpfile_name, e
# Load the specified dump file into the sbox repository using
# svnrdump load
- svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
+ original_dumpfile = open(os.path.join(svnrdump_tests_dir,
dumpfile_name),
'rb').readlines()
# Set the UUID of the sbox repository to the UUID specified in the
# dumpfile ### RA layer doesn't have a set_uuid functionality
- uuid = svnrdump_dumpfile[2].split(' ')[1][:-1]
+ uuid = original_dumpfile[2].split(' ')[1][:-1]
svntest.actions.run_and_verify_svnadmin2("Setting UUID", None, None, 0,
'setuuid', sbox.repo_dir,
uuid)
- svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
+ svntest.actions.run_and_verify_svnrdump(original_dumpfile,
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
- # Create a dump file using svnadmin dump
- svnadmin_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir,
+ # Re-dump the rdump-loaded repo using svnadmin dump
+ resulted_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir,
expect_deltas)
if expected_dumpfile_name:
- svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
+ expected_dumpfile = open(os.path.join(svnrdump_tests_dir,
expected_dumpfile_name),
'rb').readlines()
# Compare the output from stdout
svntest.verify.compare_and_display_lines(
- "Dump files", "DUMP", svnrdump_dumpfile, svnadmin_dumpfile)
+ "Dump files", "DUMP", expected_dumpfile, resulted_dumpfile)
else:
- compare_repos_dumps(sbox, svnrdump_dumpfile)
+ expected_dumpfile = original_dumpfile
+ compare_repos_dumps(sbox, expected_dumpfile)
######################################################################
# Tests
@@ -799,6 +801,105 @@ def load_prop_change_in_non_deltas_dump(
[], [], 0,
'-q', 'load', sbox.repo_url)
+#----------------------------------------------------------------------
+
+@Issue(4476)
+def dump_mergeinfo_contains_r0(sbox):
+ "dump: mergeinfo that contains r0"
+ ### We pass the original dump file name as 'expected_dumpfile_name' because
+ ### run_dump_test is currently broken when we don't.
+ run_dump_test(sbox, "mergeinfo-contains-r0.dump",
+ bypass_prop_validation=True)
+
+#----------------------------------------------------------------------
+
+@XFail()
+@Issue(4476)
+def load_mergeinfo_contains_r0(sbox):
+ "load: mergeinfo that contains r0"
+ run_load_test(sbox, "mergeinfo-contains-r0.dump",
+ expected_dumpfile_name="mergeinfo-contains-r0.expected.dump")
+
+#----------------------------------------------------------------------
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, the copy source does
+# not exist and the failure mode is to error out.
+@XFail()
+@Issue(4551)
+def load_non_deltas_copy_with_props(sbox):
+ "load non-deltas copy with props"
+ sbox.build()
+
+ # Set props on a file and on a dir and on a child of the dir to be copied
+ sbox.simple_propset('p', 'v', 'A/mu', 'A/B', 'A/B/E')
+ sbox.simple_commit()
+ sbox.simple_update() # avoid mixed-rev
+
+ # Case (1): Copy file/dir, not replacing anything; the copy target path
+ # at (new rev - 1) does not exist
+ sbox.simple_copy('A/mu@2', 'A/mu_COPY')
+ sbox.simple_copy('A/B@2', 'A/B_COPY')
+ # On the copy, delete a prop
+ sbox.simple_propdel('p', 'A/mu_COPY', 'A/B_COPY', 'A/B_COPY/E')
+
+ sbox.simple_commit()
+
+ # Dump with 'svnadmin' (non-deltas mode)
+ dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+ # Load with 'svnrdump'
+ new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+ svntest.main.create_repos(new_repo_dir)
+ svntest.actions.enable_revprop_changes(new_repo_dir)
+ svntest.actions.run_and_verify_svnrdump(dumpfile,
+ svntest.verify.AnyOutput,
+ [], 0, 'load', new_repo_url)
+ # For regression test purposes, all we require is that the 'load'
+ # doesn't throw an error
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, the copy source does
+# exist and the failure mode is to fail to delete a property.
+@XFail()
+@Issue(4551)
+def load_non_deltas_replace_copy_with_props(sbox):
+ "load non-deltas replace© with props"
+ sbox.build()
+
+ # Set props on a file and on a dir
+ sbox.simple_propset('p', 'v', 'A/mu', 'A/B')
+ sbox.simple_commit()
+ sbox.simple_update() # avoid mixed-rev
+
+ # Case (2): Copy file/dir, replacing something; the copy target path
+ # at (new rev - 1) exists and has no property named 'p'
+ sbox.simple_rm('A/D/gamma', 'A/C')
+ sbox.simple_copy('A/mu@2', 'A/D/gamma')
+ sbox.simple_copy('A/B@2', 'A/C')
+ # On the copy, delete a prop that isn't present on the replaced node
+ sbox.simple_propdel('p', 'A/D/gamma', 'A/C')
+
+ sbox.simple_commit()
+
+ # Dump with 'svnadmin' (non-deltas mode)
+ dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+ # Load with 'svnrdump'
+ new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+ svntest.main.create_repos(new_repo_dir)
+ svntest.actions.enable_revprop_changes(new_repo_dir)
+ svntest.actions.run_and_verify_svnrdump(dumpfile,
+ svntest.verify.AnyOutput,
+ [], 0, 'load', new_repo_url)
+
+ # Check that property 'p' really was deleted on each copied node
+ for tgt_path in ['A/D/gamma', 'A/C']:
+ _, out, _ = svntest.main.run_svn(None, 'proplist',
+ new_repo_url + '/' + tgt_path)
+ expected = []
+ actual = out[1:]
+ svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
########################################################################
# Run the tests
@@ -855,6 +956,10 @@ test_list = [ None,
only_trunk_range_dump,
only_trunk_A_range_dump,
load_prop_change_in_non_deltas_dump,
+ dump_mergeinfo_contains_r0,
+ load_mergeinfo_contains_r0,
+ load_non_deltas_copy_with_props,
+ load_non_deltas_replace_copy_with_props,
]
if __name__ == '__main__':
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnsync_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/svnsync_tests.py Fri Jan 16 14:01:35 2015
@@ -209,8 +209,12 @@ def setup_and_sync(sbox, dump_file_conte
return dest_sbox
-def verify_mirror(dest_sbox, src_sbox):
- """Compare the contents of the DEST_SBOX repository with EXP_DUMP_FILE_CONTENTS."""
+def verify_mirror(dest_sbox, exp_dump_file_contents):
+ """Compare the contents of the mirror repository in DEST_SBOX with
+ EXP_DUMP_FILE_CONTENTS, by comparing the parsed dump stream content.
+
+ First remove svnsync rev-props from the DEST_SBOX repository.
+ """
# Remove some SVNSync-specific housekeeping properties from the
# mirror repository in preparation for the comparison dump.
@@ -222,10 +226,9 @@ def verify_mirror(dest_sbox, src_sbox):
# Create a dump file from the mirror repository.
dest_dump = svntest.actions.run_and_verify_dump(dest_sbox.repo_dir)
- src_dump = svntest.actions.run_and_verify_dump(src_sbox.repo_dir)
svntest.verify.compare_dump_files(
- "Dump files", "DUMP", src_dump, dest_dump)
+ "Dump files", "DUMP", exp_dump_file_contents, dest_dump)
def run_test(sbox, dump_file_name, subdir=None, exp_dump_file_name=None,
bypass_prop_validation=False, source_prop_encoding=None,
@@ -251,16 +254,12 @@ or another dump file."""
# dump file (used to create the master repository) or another specified dump
# file.
if exp_dump_file_name:
- build_repos(sbox)
- svntest.actions.run_and_verify_load(sbox.repo_dir,
- open(os.path.join(svnsync_tests_dir,
- exp_dump_file_name),
- 'rb').readlines())
- src_sbox = sbox
+ exp_dump_file_contents = open(os.path.join(svnsync_tests_dir,
+ exp_dump_file_name), 'rb').readlines()
else:
- src_sbox = sbox
+ exp_dump_file_contents = master_dumpfile_contents
- verify_mirror(dest_sbox, sbox)
+ verify_mirror(dest_sbox, exp_dump_file_contents)
@@ -564,9 +563,7 @@ def delete_revprops(sbox):
run_copy_revprops(dest_sbox.repo_url, sbox.repo_url)
# Does the result look as we expected?
- build_repos(sbox)
- svntest.actions.run_and_verify_load(sbox.repo_dir, expected_contents)
- verify_mirror(dest_sbox, sbox)
+ verify_mirror(dest_sbox, expected_contents)
@Issue(3870)
@SkipUnless(svntest.main.is_posix_os)
@@ -576,6 +573,15 @@ def fd_leak_sync_from_serf_to_local(sbox
resource.setrlimit(resource.RLIMIT_NOFILE, (128, 128))
run_test(sbox, "largemods.dump", is_src_ra_local=None, is_dest_ra_local=True)
+#----------------------------------------------------------------------
+
+@Issue(4476)
+def mergeinfo_contains_r0(sbox):
+ "mergeinfo contains r0"
+ run_test(sbox, "mergeinfo-contains-r0.dump",
+ exp_dump_file_name="mergeinfo-contains-r0.expected.dump",
+ bypass_prop_validation=True)
+
########################################################################
# Run the tests
@@ -612,6 +618,7 @@ test_list = [ None,
descend_into_replace,
delete_revprops,
fd_leak_sync_from_serf_to_local, # calls setrlimit
+ mergeinfo_contains_r0,
]
if __name__ == '__main__':
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/svntest/main.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/svntest/main.py Fri Jan 16 14:01:35 2015
@@ -544,6 +544,15 @@ def run_command_stdin(command, error_exp
and not any(map(lambda arg: 'prop_tests-12' in arg, varargs)):
raise Failure("Repository diskpath in %s: %r" % (name, lines))
+ valgrind_diagnostic = False
+ # A valgrind diagnostic will raise a failure if the command is
+ # expected to run without error. When an error is expected any
+ # subsequent error pattern matching is usually lenient and will not
+ # detect the diagnostic so make sure a failure is raised here.
+ if error_expected and stderr_lines:
+ if any(map(lambda arg: re.match('==[0-9]+==', arg), stderr_lines)):
+ valgrind_diagnostic = True
+
stop = time.time()
logger.info('<TIME = %.6f>' % (stop - start))
for x in stdout_lines:
@@ -551,7 +560,8 @@ def run_command_stdin(command, error_exp
for x in stderr_lines:
logger.info(x.rstrip())
- if (not error_expected) and ((stderr_lines) or (exit_code != 0)):
+ if (((not error_expected) and ((stderr_lines) or (exit_code != 0)))
+ or valgrind_diagnostic):
for x in stderr_lines:
logger.warning(x.rstrip())
if len(varargs) <= 5:
Modified: subversion/branches/svn-auth-x509/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/cmdline/update_tests.py?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/cmdline/update_tests.py Fri Jan 16 14:01:35 2015
@@ -6517,7 +6517,6 @@ def windows_update_backslash(sbox):
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
svntest.actions.run_and_verify_status(wc_dir, expected_status)
-@XFail() # Tries to modify unlocked part of working copy; found via r1561425
def update_moved_away(sbox):
"update subtree of moved away"
Modified: subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs/fs-test.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs/fs-test.c Fri Jan 16 14:01:35 2015
@@ -6539,6 +6539,163 @@ test_fs_merge(const svn_test_opts_t *opt
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_fsfs_config_opts(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ apr_hash_t *fs_config;
+ svn_fs_t *fs;
+ const svn_fs_info_placeholder_t *fs_info;
+ const svn_fs_fsfs_info_t *fsfs_info;
+
+ /* Bail (with SKIP) on known-untestable scenarios */
+ if (strcmp(opts->fs_type, "fsfs") != 0)
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "this will test FSFS repositories only");
+
+ /* Remove the test directory from previous runs. */
+ SVN_ERR(svn_io_remove_dir2("test-fsfs-config-opts", TRUE, NULL, NULL, pool));
+
+ /* Create the test directory and add it to the test cleanup list. */
+ SVN_ERR(svn_io_dir_make("test-fsfs-config-opts", APR_OS_DEFAULT, pool));
+ svn_test_add_dir_cleanup("test-fsfs-config-opts");
+
+ /* Create an FSFS filesystem with default config.*/
+ fs_config = apr_hash_make(pool);
+ svn_hash_sets(fs_config, SVN_FS_CONFIG_FS_TYPE, SVN_FS_TYPE_FSFS);
+ SVN_ERR(svn_fs_create(&fs, "test-fsfs-config-opts/default", fs_config, pool));
+
+ /* Re-open FS to test the data on disk. */
+ SVN_ERR(svn_fs_open2(&fs, "test-fsfs-config-opts/default", NULL, pool, pool));
+
+ SVN_ERR(svn_fs_info(&fs_info, fs, pool, pool));
+ SVN_TEST_STRING_ASSERT(fs_info->fs_type, SVN_FS_TYPE_FSFS);
+ fsfs_info = (const void *) fs_info;
+
+ /* Check FSFS specific info. Don't check the SHARD_SIZE, because it depends
+ * on a compile-time constant and may be overridden. */
+ SVN_TEST_ASSERT(fsfs_info->log_addressing);
+ SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev == 0);
+
+ /* Create an FSFS filesystem with custom settings: disabled log-addressing
+ * and custom shard size (123). */
+ fs_config = apr_hash_make(pool);
+ svn_hash_sets(fs_config, SVN_FS_CONFIG_FS_TYPE, SVN_FS_TYPE_FSFS);
+ svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_LOG_ADDRESSING, "false");
+ svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_SHARD_SIZE, "123");
+ SVN_ERR(svn_fs_create(&fs, "test-fsfs-config-opts/custom", fs_config, pool));
+
+ /* Re-open FS to test the data on disk. */
+ SVN_ERR(svn_fs_open2(&fs, "test-fsfs-config-opts/custom", NULL, pool, pool));
+
+ SVN_ERR(svn_fs_info(&fs_info, fs, pool, pool));
+ SVN_TEST_STRING_ASSERT(fs_info->fs_type, SVN_FS_TYPE_FSFS);
+ fsfs_info = (const void *) fs_info;
+
+ /* Check FSFS specific info, including the SHARD_SIZE. */
+ SVN_TEST_ASSERT(fsfs_info->log_addressing == FALSE);
+ SVN_TEST_ASSERT(fsfs_info->shard_size == 123);
+ SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev == 0);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_txn_pool_lifetime(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ /* Technically, the FS API makes no assumption on the lifetime of logically
+ * dependent objects. In particular, a txn root object may get destroyed
+ * after the FS object that it has been built upon. Actual data access is
+ * implied to be invalid without a valid svn_fs_t.
+ *
+ * This test verifies that at least the destruction order of those two
+ * objects is arbitrary.
+ */
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+
+ /* We will allocate FS in FS_POOL. Using a separate allocator makes
+ * sure that we actually free the memory when destroying the pool.
+ */
+ apr_allocator_t *fs_allocator = svn_pool_create_allocator(FALSE);
+ apr_pool_t *fs_pool = apr_allocator_owner_get(fs_allocator);
+
+ /* Create a new repo. */
+ SVN_ERR(svn_test__create_fs(&fs, "test-repo-pool-lifetime",
+ opts, fs_pool));
+
+ /* Create a TXN_ROOT referencing FS. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+ /* Destroy FS. Depending on the actual allocator implementation,
+ * these memory pages becomes inaccessible. */
+ svn_pool_destroy(fs_pool);
+
+ /* Unclean implementations will try to access FS and may segfault here. */
+ svn_fs_close_root(txn_root);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_modify_txn_being_written(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ /* FSFS has a limitation (and check) that only one file can be
+ * modified in TXN at time: see r861812 and svn_fs_apply_text() docstring.
+ * This is regression test for this behavior. */
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ const char *txn_name;
+ svn_fs_root_t *txn_root;
+ svn_stream_t *foo_contents;
+ svn_stream_t *bar_contents;
+
+ /* Bail (with success) on known-untestable scenarios */
+ if (strcmp(opts->fs_type, SVN_FS_TYPE_FSFS) != 0)
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "this will test FSFS repositories only");
+
+ /* Create a new repo. */
+ SVN_ERR(svn_test__create_fs(&fs, "test-modify-txn-being-written",
+ opts, pool));
+
+ /* Create a TXN_ROOT referencing FS. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+ SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+ /* Make file /foo and open for writing.*/
+ SVN_ERR(svn_fs_make_file(txn_root, "/foo", pool));
+ SVN_ERR(svn_fs_apply_text(&foo_contents, txn_root, "/foo", NULL, pool));
+
+ /* Attempt to modify another file '/bar' -- FSFS doesn't allow this. */
+ SVN_ERR(svn_fs_make_file(txn_root, "/bar", pool));
+ SVN_TEST_ASSERT_ERROR(
+ svn_fs_apply_text(&bar_contents, txn_root, "/bar", NULL, pool),
+ SVN_ERR_FS_REP_BEING_WRITTEN);
+
+ /* *Reopen TXN. */
+ SVN_ERR(svn_fs_open_txn(&txn, fs, txn_name, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+ /* Check that file '/bar' still cannot be modified */
+ SVN_TEST_ASSERT_ERROR(
+ svn_fs_apply_text(&bar_contents, txn_root, "/bar", NULL, pool),
+ SVN_ERR_FS_REP_BEING_WRITTEN);
+
+ /* Close file '/foo'. */
+ SVN_ERR(svn_stream_close(foo_contents));
+
+ /* Now file '/bar' can be modified. */
+ SVN_ERR(svn_fs_apply_text(&bar_contents, txn_root, "/bar", NULL, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -6662,6 +6819,12 @@ static struct svn_test_descriptor_t test
"get a delta stream on a file"),
SVN_TEST_OPTS_PASS(test_fs_merge,
"get merging txns with newer revisions"),
+ SVN_TEST_OPTS_PASS(test_fsfs_config_opts,
+ "test creating FSFS repository with different opts"),
+ SVN_TEST_OPTS_PASS(test_txn_pool_lifetime,
+ "test pool lifetime dependencies with txn roots"),
+ SVN_TEST_OPTS_PASS(test_modify_txn_being_written,
+ "test modify txn being written in FSFS"),
SVN_TEST_NULL
};
Propchange: subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs_fs/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Jan 16 14:01:35 2015
@@ -4,8 +4,7 @@ Release
test-repo-*
upgrade_*
fs-pack-test
-fs-fs-fuzzy-test
-fs-fs-pack-test
+fs-fs-*-test
test-get-set-revprop-packed-fs
get_set_multiple_huge_revprops_packed_fs
*.o
Modified: subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c?rev=1652409&r1=1652408&r2=1652409&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c (original)
+++ subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c Fri Jan 16 14:01:35 2015
@@ -133,7 +133,7 @@ fuzzing_1_byte_1_rev(const char *repo_na
/* Let us know where we were too strict ... */
printf("Detected case change in checksum digest at offset 0x%"
APR_UINT64_T_HEX_FMT " (%" APR_OFF_T_FMT ") in r%ld: "
- "%c -> %c\n", i, i, revision, c_old, c_new);
+ "%c -> %c\n", (apr_uint64_t)i, i, revision, c_old, c_new);
SVN_ERR(err);
}
@@ -143,7 +143,7 @@ fuzzing_1_byte_1_rev(const char *repo_na
/* Let us know where we miss changes ... */
printf("Undetected mod at offset 0x%"APR_UINT64_T_HEX_FMT
" (%"APR_OFF_T_FMT") in r%ld: 0x%02x -> 0x%02x\n",
- i, i, revision, c_old, c_new);
+ (apr_uint64_t)i, i, revision, c_old, c_new);
SVN_TEST_ASSERT(err);
}