You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/12/01 20:37:31 UTC
svn commit: r1546842 - in /subversion/branches/log-addressing: ./
subversion/bindings/javahl/tests/org/apache/subversion/javahl/
subversion/include/ subversion/libsvn_client/ subversion/libsvn_fs/
subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/ subver...
Author: stefan2
Date: Sun Dec 1 19:37:30 2013
New Revision: 1546842
URL: http://svn.apache.org/r1546842
Log:
On the log-addressing branch: sync with the parent branch and
resolve a few trivial conflicts.
Modified:
subversion/branches/log-addressing/ (props changed)
subversion/branches/log-addressing/CHANGES
subversion/branches/log-addressing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
subversion/branches/log-addressing/subversion/include/svn_fs.h
subversion/branches/log-addressing/subversion/libsvn_client/merge.c
subversion/branches/log-addressing/subversion/libsvn_fs/editor.c
subversion/branches/log-addressing/subversion/libsvn_fs/fs-loader.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/transaction.c
subversion/branches/log-addressing/subversion/libsvn_fs_x/ (props changed)
subversion/branches/log-addressing/subversion/libsvn_fs_x/fs_x.c
subversion/branches/log-addressing/subversion/libsvn_fs_x/transaction.c
subversion/branches/log-addressing/subversion/libsvn_repos/dump.c
subversion/branches/log-addressing/subversion/libsvn_repos/fs-wrap.c
subversion/branches/log-addressing/subversion/libsvn_subr/config_file.c
subversion/branches/log-addressing/subversion/libsvn_subr/config_impl.h
subversion/branches/log-addressing/subversion/libsvn_subr/config_win.c
subversion/branches/log-addressing/subversion/svn/mergeinfo-cmd.c
subversion/branches/log-addressing/subversion/svnadmin/svnadmin.c
subversion/branches/log-addressing/subversion/tests/cmdline/mergeinfo_tests.py
subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests.py
subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests_data/normalization_check.dump
subversion/branches/log-addressing/subversion/tests/cmdline/svntest/main.py
subversion/branches/log-addressing/subversion/tests/libsvn_fs/fs-test.c
subversion/branches/log-addressing/subversion/tests/libsvn_fs_x/ (props changed)
subversion/branches/log-addressing/subversion/tests/libsvn_repos/repos-test.c
subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c
subversion/branches/log-addressing/subversion/tests/svn_test_main.c
Propchange: subversion/branches/log-addressing/
------------------------------------------------------------------------------
Merged /subversion/branches/fsfs-improvements:r1545956-1546837
Merged /subversion/trunk:r1545955-1546835
Merged /subversion/branches/verify-keep-going:r1492640-1546110
Modified: subversion/branches/log-addressing/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/CHANGES?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/CHANGES (original)
+++ subversion/branches/log-addressing/CHANGES Sun Dec 1 19:37:30 2013
@@ -10,6 +10,7 @@ http://svn.apache.org/repos/asf/subversi
- Minor new features and improvements:
* new 'diff-ignore-content-type' runtime configuration option.
* new option for 'svnadmin verify': --check-ucs-normalization.
+ * new option for 'svnadmin verify': --keep-going.
- Client-side bugfixes:
Modified: subversion/branches/log-addressing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/log-addressing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Sun Dec 1 19:37:30 2013
@@ -670,14 +670,17 @@ public class SVNRemoteTests extends SVNT
ISVNRemote session = getSession();
byte[] ignoreval = "*.pyc\n.gitignore\n".getBytes(UTF8);
+ byte[] binaryval = new byte[]{(byte)0, (byte)13, (byte)255, (byte)8,
+ (byte)127, (byte)128, (byte)129};
HashMap<String, byte[]> props = new HashMap<String, byte[]>();
props.put("svn:ignore", ignoreval);
+ props.put("binaryprop", binaryval);
CommitContext cc =
(cb != null
- ? new CommitContext(session, "Add svn:ignore",
+ ? new CommitContext(session, "Add svn:ignore and binaryprop",
cb.getBase, cb.getProps, cb.getKind)
- : new CommitContext(session, "Add svn:ignore"));
+ : new CommitContext(session, "Add svn:ignore and binaryprop"));
try {
cc.editor.alterDirectory("", 1, null, props);
cc.editor.complete();
@@ -692,6 +695,11 @@ public class SVNRemoteTests extends SVNT
"svn:ignore",
Revision.HEAD,
Revision.HEAD)));
+ assertTrue(Arrays.equals(binaryval,
+ client.propertyGet(session.getSessionUrl(),
+ "binaryprop",
+ Revision.HEAD,
+ Revision.HEAD)));
}
public void testEditorSetDirProps() throws Exception
Modified: subversion/branches/log-addressing/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/include/svn_fs.h?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/include/svn_fs.h (original)
+++ subversion/branches/log-addressing/subversion/include/svn_fs.h Sun Dec 1 19:37:30 2013
@@ -908,10 +908,9 @@ svn_fs_unparse_id(const svn_fs_id_t *id,
* pairs. When you commit a transaction, all of its properties become
* unversioned revision properties of the new revision. (There is one
* exception: the svn:date property will be automatically set on new
- * transactions to the date that the transaction was created, and will
+ * transactions to the date that the transaction was created, and can
* be overwritten when the transaction is committed by the current
- * time; changes to a transaction's svn:date property will not affect
- * its committed value.)
+ * time; see svn_fs_commit_txn2.)
*
* Transaction names are guaranteed to contain only letters (upper-
* and lower-case), digits, `-', and `.', from the ASCII character
@@ -1006,6 +1005,16 @@ svn_fs_begin_txn(svn_fs_txn_t **txn_p,
* a new filesystem revision containing the changes made in @a txn,
* storing that new revision number in @a *new_rev, and return zero.
*
+ * If @a set_timestamp is FALSE any svn:date on the transaction will
+ * be become the unversioned property svn:date on the revision.
+ * svn:date can have any value, it does not have to be a timestamp.
+ * If the transaction has no svn:date the revision will have no
+ * svn:date.
+ *
+ * If @a set_timestamp is TRUE the new revision will have svn:date set
+ * to the current time at some point during the commit and any
+ * svn:date on the transaction will be lost.
+ *
* If @a conflict_p is non-zero, use it to provide details on any
* conflicts encountered merging @a txn with the most recent committed
* revisions. If a conflict occurs, set @a *conflict_p to the path of
@@ -1056,7 +1065,10 @@ svn_fs_commit_txn2(const char **conflict
/*
* Same as svn_fs_commit_txn2(), but with @a set_timestamp
* always set to @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.8 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_fs_commit_txn(const char **conflict_p,
svn_revnum_t *new_rev,
Modified: subversion/branches/log-addressing/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_client/merge.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_client/merge.c Sun Dec 1 19:37:30 2013
@@ -12681,7 +12681,8 @@ svn_client_get_merging_summary(svn_boole
target_is_wc = (! svn_path_is_url(target_path_or_url))
&& (target_revision->kind == svn_opt_revision_unspecified
- || target_revision->kind == svn_opt_revision_working);
+ || target_revision->kind == svn_opt_revision_working
+ || target_revision->kind == svn_opt_revision_base);
if (target_is_wc)
{
const char *target_abspath;
Modified: subversion/branches/log-addressing/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs/editor.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs/editor.c Sun Dec 1 19:37:30 2013
@@ -789,10 +789,11 @@ svn_fs__editor_commit(svn_revnum_t *revi
it placed into RESULT_POOL. */
if (!err)
- err = svn_fs_commit_txn(&inner_conflict_path,
- revision,
- eb->txn,
- scratch_pool);
+ err = svn_fs_commit_txn2(&inner_conflict_path,
+ revision,
+ eb->txn,
+ TRUE,
+ scratch_pool);
if (SVN_IS_VALID_REVNUM(*revision))
{
if (err)
Modified: subversion/branches/log-addressing/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs/fs-loader.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs/fs-loader.c Sun Dec 1 19:37:30 2013
@@ -44,6 +44,7 @@
#include "svn_string.h"
#include "svn_sorts.h"
+#include "private/svn_atomic.h"
#include "private/svn_fs_private.h"
#include "private/svn_fs_util.h"
#include "private/svn_utf_private.h"
@@ -62,8 +63,9 @@
/* A pool common to all FS objects. See the documentation on the
open/create functions in fs-loader.h and for svn_fs_initialize(). */
-static apr_pool_t *common_pool;
-svn_mutex__t *common_pool_lock;
+static apr_pool_t *common_pool = NULL;
+static svn_mutex__t *common_pool_lock = NULL;
+static svn_atomic_t common_pool_initialized = FALSE;
/* --- Utility functions for the loader --- */
@@ -196,8 +198,7 @@ get_library_vtable_direct(fs_library_vta
unloaded. This function makes a best effort by creating the
common pool as a child of the global pool; the window of failure
due to thread collision is small. */
- if (!common_pool)
- SVN_ERR(svn_fs_initialize(NULL));
+ SVN_ERR(svn_fs_initialize(NULL));
/* Invoke the FS module's initfunc function with the common
pool protected by a lock. */
@@ -280,8 +281,8 @@ get_library_vtable(fs_library_vtable_t *
if (!known)
{
fst = &(*fst)->next;
- if (!common_pool) /* Best-effort init, see get_library_vtable_direct. */
- SVN_ERR(svn_fs_initialize(NULL));
+ /* Best-effort init, see get_library_vtable_direct. */
+ SVN_ERR(svn_fs_initialize(NULL));
SVN_MUTEX__WITH_LOCK(common_pool_lock,
get_or_allocate_third(fst, fs_type));
known = TRUE;
@@ -371,16 +372,15 @@ write_fs_type(const char *path, const ch
static apr_status_t uninit(void *data)
{
common_pool = NULL;
+ common_pool_lock = NULL;
+ common_pool_initialized = 0;
+
return APR_SUCCESS;
}
-svn_error_t *
-svn_fs_initialize(apr_pool_t *pool)
+static svn_error_t *
+synchronized_initialize(void *baton, apr_pool_t *pool)
{
- /* Protect against multiple calls. */
- if (common_pool)
- return SVN_NO_ERROR;
-
common_pool = svn_pool_create(pool);
base_defn.next = NULL;
SVN_ERR(svn_mutex__init(&common_pool_lock, TRUE, common_pool));
@@ -395,6 +395,15 @@ svn_fs_initialize(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_fs_initialize(apr_pool_t *pool)
+{
+ /* Protect against multiple calls. */
+ return svn_error_trace(svn_atomic__init_once(&common_pool_initialized,
+ synchronized_initialize,
+ NULL, pool));
+}
+
/* A default warning handling function. */
static void
default_warning_func(void *baton, svn_error_t *err)
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c Sun Dec 1 19:37:30 2013
@@ -56,6 +56,7 @@ recover_get_largest_revision(svn_fs_t *f
svn_error_t *err;
svn_fs_fs__revision_file_t *file;
svn_pool_clear(iterpool);
+ svn_pool_clear(iterpool);
err = svn_fs_fs__open_pack_or_rev_file(&file, fs, right, iterpool);
if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
@@ -79,6 +80,7 @@ recover_get_largest_revision(svn_fs_t *f
svn_error_t *err;
svn_fs_fs__revision_file_t *file;
svn_pool_clear(iterpool);
+ svn_pool_clear(iterpool);
err = svn_fs_fs__open_pack_or_rev_file(&file, fs, probe, iterpool);
if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/transaction.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/transaction.c Sun Dec 1 19:37:30 2013
@@ -3736,7 +3736,11 @@ commit_body(void *baton, apr_pool_t *poo
race with another caller writing to the prototype revision file
before we commit it. */
- /* Remove any temporary txn props representing 'flags'. */
+ /* Remove any temporary txn props representing 'flags'.
+
+ ### This is a permanent change to the transaction. If this
+ ### commit does not complete for any reason the transaction will
+ ### still exist but will have lost these properties. */
SVN_ERR(svn_fs_fs__txn_proplist(&txnprops, cb->txn, pool));
txnprop_list = apr_array_make(pool, 3, sizeof(svn_prop_t));
prop.value = NULL;
@@ -3807,7 +3811,11 @@ commit_body(void *baton, apr_pool_t *poo
new_rev, pool));
}
- /* Move the finished rev file into place. */
+ /* Move the finished rev file into place.
+
+ ### This "breaks" the transaction by removing the protorev file
+ ### but the revision is not yet complete. If this commit does
+ ### not complete for any reason the transaction will be lost. */
old_rev_filename = svn_fs_fs__path_rev_absolute(cb->fs, old_rev, pool);
rev_filename = svn_fs_fs__path_rev(cb->fs, new_rev, pool);
proto_filename = svn_fs_fs__path_txn_proto_rev(cb->fs, txn_id, pool);
Propchange: subversion/branches/log-addressing/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
Merged /subversion/branches/verify-keep-going/subversion/libsvn_fs_x:r1546002-1546110
Merged /subversion/trunk/subversion/libsvn_fs_x:r1545955-1546835
Merged /subversion/branches/fsfs-improvements/subversion/libsvn_fs_x:r1545956-1546837
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_x/fs_x.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_x/fs_x.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_x/fs_x.c Sun Dec 1 19:37:30 2013
@@ -800,7 +800,7 @@ svn_fs_x__create(svn_fs_t *fs,
case 6:
case 7:
case 8: return svn_error_create(SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL,
- _("FSFS is not compatible with Subversion prior to 1.9"));
+ _("FSX is not compatible with Subversion prior to 1.9"));
default:format = SVN_FS_X__FORMAT_NUMBER;
}
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_x/transaction.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_x/transaction.c Sun Dec 1 19:37:30 2013
@@ -2852,23 +2852,27 @@ verify_locks(svn_fs_t *fs,
/* If CHANGE is move, verify that there is no other move with the same
copy-from path in SOURCE_PATHS already (parent or sub-node moves are fine).
- Add the source path to SOURCE_PATHS after successful verification. */
+ Add the source path to SOURCE_PATHS after successful verification.
+ Allocate the hashed strings in POOL. */
static svn_error_t *
check_for_duplicate_move_source(apr_hash_t *source_paths,
- change_t *change)
+ svn_fs_path_change2_t *change,
+ apr_pool_t *pool)
{
- if ( change->info.change_kind == svn_fs_path_change_move
- || change->info.change_kind == svn_fs_path_change_movereplace)
- if (change->info.copyfrom_path)
+ if ( change->change_kind == svn_fs_path_change_move
+ || change->change_kind == svn_fs_path_change_movereplace)
+ if (change->copyfrom_path)
{
- if (apr_hash_get(source_paths, change->info.copyfrom_path,
- APR_HASH_KEY_STRING))
+ apr_size_t len = strlen(change->copyfrom_path);
+ if (apr_hash_get(source_paths, change->copyfrom_path, len))
return svn_error_createf(SVN_ERR_FS_AMBIGUOUS_MOVE, NULL,
_("Path '%s' has been moved to more than one target"),
- change->info.copyfrom_path);
+ change->copyfrom_path);
- apr_hash_set(source_paths, change->info.copyfrom_path,
- APR_HASH_KEY_STRING, change->info.copyfrom_path);
+ apr_hash_set(source_paths,
+ apr_pstrmemdup(pool, change->copyfrom_path, len),
+ len,
+ change->copyfrom_path);
}
return SVN_NO_ERROR;
@@ -2887,7 +2891,7 @@ verify_moves(svn_fs_t *fs,
{
apr_hash_t *source_paths = apr_hash_make(pool);
svn_revnum_t revision;
- apr_pool_t *iter_pool = svn_pool_create(pool);
+ apr_pool_t *iterpool = svn_pool_create(pool);
apr_hash_index_t *hi;
int i;
apr_array_header_t *moves
@@ -2901,12 +2905,12 @@ verify_moves(svn_fs_t *fs,
{
const char *path;
apr_ssize_t len;
- change_t *change;
+ svn_fs_path_change2_t *change;
apr_hash_this(hi, (const void**)&path, &len, (void**)&change);
- if ( change->info.copyfrom_path
- && ( change->info.change_kind == svn_fs_path_change_move
- || change->info.change_kind == svn_fs_path_change_movereplace))
+ if ( change->copyfrom_path
+ && ( change->change_kind == svn_fs_path_change_move
+ || change->change_kind == svn_fs_path_change_movereplace))
{
svn_sort__item_t *item = apr_array_push(moves);
item->key = path;
@@ -2914,9 +2918,9 @@ verify_moves(svn_fs_t *fs,
item->value = change;
}
- if ( change->info.change_kind == svn_fs_path_change_delete
- || change->info.change_kind == svn_fs_path_change_replace
- || change->info.change_kind == svn_fs_path_change_movereplace)
+ if ( change->change_kind == svn_fs_path_change_delete
+ || change->change_kind == svn_fs_path_change_replace
+ || change->change_kind == svn_fs_path_change_movereplace)
APR_ARRAY_PUSH(deletions, const char *) = path;
}
@@ -2947,10 +2951,9 @@ verify_moves(svn_fs_t *fs,
deleted_path);
if (relpath)
{
- change_t *closed_move = closest_move_item->value;
+ svn_fs_path_change2_t *closed_move = closest_move_item->value;
APR_ARRAY_IDX(deletions, i, const char*)
- = svn_dirent_join(closed_move->info.copyfrom_path, relpath,
- pool);
+ = svn_dirent_join(closed_move->copyfrom_path, relpath, pool);
}
}
}
@@ -2963,46 +2966,50 @@ verify_moves(svn_fs_t *fs,
for (i = 0; moves->nelts; ++i)
SVN_ERR(check_for_duplicate_move_source (source_paths,
- APR_ARRAY_IDX(moves, i, svn_sort__item_t).value));
+ APR_ARRAY_IDX(moves, i, svn_sort__item_t).value,
+ pool));
for (revision = txn_id->revision + 1; revision <= old_rev; ++revision)
{
apr_array_header_t *changes;
change_t **changes_p;
- svn_pool_clear(iter_pool);
- svn_fs_x__get_changes(&changes, fs, revision, iter_pool);
+ svn_pool_clear(iterpool);
+ svn_fs_x__get_changes(&changes, fs, revision, iterpool);
changes_p = (change_t **)&changes->elts;
for (i = 0; i < changes->nelts; ++i)
- SVN_ERR(check_for_duplicate_move_source(source_paths, changes_p[i]));
+ SVN_ERR(check_for_duplicate_move_source(source_paths,
+ &changes_p[i]->info,
+ pool));
}
/* The move source paths must been deleted in this txn. */
for (i = 0; i < moves->nelts; ++i)
{
- change_t *change = APR_ARRAY_IDX(moves, i, svn_sort__item_t).value;
+ svn_fs_path_change2_t *change
+ = APR_ARRAY_IDX(moves, i, svn_sort__item_t).value;
/* there must be a deletion of move's copy-from path
(or any of its parents) */
int closest_deletion_idx
- = svn_sort__bsearch_lower_bound(change->info.copyfrom_path, deletions,
+ = svn_sort__bsearch_lower_bound(change->copyfrom_path, deletions,
svn_sort_compare_paths);
if (closest_deletion_idx < deletions->nelts)
{
const char *closest_deleted_path
= APR_ARRAY_IDX(deletions, closest_deletion_idx, const char *);
if (!svn_dirent_is_ancestor(closest_deleted_path,
- change->info.copyfrom_path))
+ change->copyfrom_path))
return svn_error_createf(SVN_ERR_FS_INCOMPLETE_MOVE, NULL,
_("Path '%s' has been moved without being deleted"),
- change->info.copyfrom_path);
+ change->copyfrom_path);
}
}
- svn_pool_destroy(iter_pool);
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
Modified: subversion/branches/log-addressing/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_repos/dump.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_repos/dump.c Sun Dec 1 19:37:30 2013
@@ -593,12 +593,15 @@ node_must_not_exist(struct edit_baton *e
}
+static const char normalized_unique[] = "normalized_unique";
+static const char normalized_collision[] = "normalized_collision";
+
static svn_error_t *
-check_ucs_normalization(const char *path,
- svn_node_kind_t kind,
- svn_repos_notify_func_t notify_func,
- void *notify_baton,
- apr_pool_t *scratch_pool)
+check_path_normalization(const char *path,
+ svn_node_kind_t kind,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
{
const char *const name = svn_relpath_basename(path, scratch_pool);
if (!svn_utf__is_normalized(name, scratch_pool))
@@ -626,11 +629,62 @@ check_ucs_normalization(const char *path
}
+/* Baton for extract_mergeinfo_paths */
+struct extract_mergeinfo_paths_baton
+{
+ apr_hash_t *result;
+ svn_boolean_t normalize;
+ svn_membuf_t buffer;
+};
+
+/* Hash iterator that uniquifies all keys into a single hash table,
+ optionally normalizing them first. */
+static svn_error_t *
+extract_mergeinfo_paths(void *baton, const void *key, apr_ssize_t klen,
+ void *val, apr_pool_t *iterpool)
+{
+ struct extract_mergeinfo_paths_baton *const xb = baton;
+ if (xb->normalize)
+ {
+ const char *normkey;
+ SVN_ERR(svn_utf__normalize(&normkey, key, klen, &xb->buffer));
+ svn_hash_sets(xb->result,
+ apr_pstrdup(xb->buffer.pool, normkey),
+ normalized_unique);
+ }
+ else
+ apr_hash_set(xb->result,
+ apr_pmemdup(xb->buffer.pool, key, klen + 1), klen,
+ normalized_unique);
+ return SVN_NO_ERROR;
+}
+
+/* Baton for filter_mergeinfo_paths */
+struct filter_mergeinfo_paths_baton
+{
+ apr_hash_t *paths;
+ svn_membuf_t buffer;
+};
+
+/* Compare two sets of denormalized paths from mergeinfo entries,
+ removing duplicates. */
+static svn_error_t *
+filter_mergeinfo_paths(void *baton, const void *key, apr_ssize_t klen,
+ void *val, apr_pool_t *iterpool)
+{
+ struct filter_mergeinfo_paths_baton *const fb = baton;
+
+ if (apr_hash_get(fb->paths, key, klen))
+ apr_hash_set(fb->paths, key, klen, NULL);
+
+ return SVN_NO_ERROR;
+}
+
/* Baton used by the check_mergeinfo_normalization hash iterator. */
-struct check_mergeinfo_normalization_baton
+struct verify_mergeinfo_normalization_baton
{
const char* path;
- apr_hash_t *normalized;
+ apr_hash_t *normalized_paths;
svn_membuf_t buffer;
svn_repos_notify_func_t notify_func;
void *notify_baton;
@@ -639,53 +693,116 @@ struct check_mergeinfo_normalization_bat
/* Hash iterator that verifies normalization and collision of paths in
an svn:mergeinfo property. */
static svn_error_t *
-check_mergeinfo_normalization(void *baton, const void *key, apr_ssize_t klen,
- void *val, apr_pool_t *pool)
+verify_mergeinfo_normalization(void *baton, const void *key, apr_ssize_t klen,
+ void *val, apr_pool_t *iterpool)
{
- static const char unique[] = "unique";
- static const char collision[] = "collision";
-
- struct check_mergeinfo_normalization_baton *const check_baton = baton;
+ struct verify_mergeinfo_normalization_baton *const vb = baton;
const char *const path = key;
const char *normpath;
const char *found;
- SVN_ERR(svn_utf__normalize(&normpath, path, klen, &check_baton->buffer));
-
- found = svn_hash_gets(check_baton->normalized, normpath);
- if (!found)
+ SVN_ERR(svn_utf__normalize(&normpath, path, klen, &vb->buffer));
+ if (0 != strcmp(path, normpath))
{
- if (0 != strcmp(path, normpath))
- {
- /* Report denormlized mergeinfo path */
- svn_repos_notify_t *const notify =
- svn_repos_notify_create(svn_repos_notify_warning, pool);
- notify->warning = svn_repos_notify_warning_denormalized_mergeinfo;
- notify->warning_str = apr_psprintf(
- pool, _("Denormalized path '%s' in %s property of '%s'"),
- path, SVN_PROP_MERGEINFO, check_baton->path);
- check_baton->notify_func(check_baton->notify_baton, notify, pool);
- }
- svn_hash_sets(check_baton->normalized,
- apr_pstrdup(pool, normpath), unique);
+ /* Report denormlized mergeinfo path */
+ svn_repos_notify_t *const notify =
+ svn_repos_notify_create(svn_repos_notify_warning, iterpool);
+ notify->warning = svn_repos_notify_warning_denormalized_mergeinfo;
+ notify->warning_str = apr_psprintf(
+ iterpool, _("Denormalized path '%s' in %s property of '%s'"),
+ path, SVN_PROP_MERGEINFO, vb->path);
+ vb->notify_func(vb->notify_baton, notify, iterpool);
}
- else if (found == collision)
+
+ found = svn_hash_gets(vb->normalized_paths, normpath);
+ if (!found)
+ svn_hash_sets(vb->normalized_paths,
+ apr_pstrdup(vb->buffer.pool, normpath),
+ normalized_unique);
+ else if (found == normalized_collision)
/* Skip already reported collision */;
else
{
/* Report path collision in mergeinfo */
- svn_repos_notify_t *const notify =
- svn_repos_notify_create(svn_repos_notify_warning, pool);
+ svn_repos_notify_t *notify;
+
+ svn_hash_sets(vb->normalized_paths,
+ apr_pstrdup(vb->buffer.pool, normpath),
+ normalized_collision);
+
+ notify = svn_repos_notify_create(svn_repos_notify_warning, iterpool);
notify->warning = svn_repos_notify_warning_mergeinfo_collision;
notify->warning_str = apr_psprintf(
- pool, _("Duplicate representation of path '%s'"
+ iterpool, _("Duplicate representation of path '%s'"
" in %s property of '%s'"),
- normpath, SVN_PROP_MERGEINFO, check_baton->path);
- check_baton->notify_func(check_baton->notify_baton, notify, pool);
- svn_hash_sets(check_baton->normalized,
- apr_pstrdup(pool, normpath), collision);
+ normpath, SVN_PROP_MERGEINFO, vb->path);
+ vb->notify_func(vb->notify_baton, notify, iterpool);
+ }
+ return SVN_NO_ERROR;
+}
+
+/* Check UCS normalization of mergeinfo for PATH. NEW_MERGEINFO is the
+ svn:mergeinfo property value being set; OLD_MERGEINFO is the
+ previous property value, which may be NULL. Only the paths that
+ were added in are checked, including collision checks. This
+ minimizes the number of notifications we generate for a given
+ mergeinfo property. */
+static svn_error_t *
+check_mergeinfo_normalization(const char *path,
+ const char *new_mergeinfo,
+ const char *old_mergeinfo,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ apr_pool_t *pool)
+{
+ svn_mergeinfo_t mergeinfo;
+ apr_hash_t *normalized_paths;
+ apr_hash_t *added_paths;
+ struct extract_mergeinfo_paths_baton extract_baton;
+ struct verify_mergeinfo_normalization_baton verify_baton;
+
+ SVN_ERR(svn_mergeinfo_parse(&mergeinfo, new_mergeinfo, pool));
+
+ extract_baton.result = apr_hash_make(pool);
+ extract_baton.normalize = FALSE;
+ svn_membuf__create(&extract_baton.buffer, 0, pool);
+ SVN_ERR(svn_iter_apr_hash(NULL, mergeinfo,
+ extract_mergeinfo_paths,
+ &extract_baton, pool));
+ added_paths = extract_baton.result;
+
+ if (old_mergeinfo)
+ {
+ struct filter_mergeinfo_paths_baton filter_baton;
+ svn_mergeinfo_t oldinfo;
+
+ extract_baton.result = apr_hash_make(pool);
+ extract_baton.normalize = TRUE;
+ SVN_ERR(svn_mergeinfo_parse(&oldinfo, old_mergeinfo, pool));
+ SVN_ERR(svn_iter_apr_hash(NULL, oldinfo,
+ extract_mergeinfo_paths,
+ &extract_baton, pool));
+ normalized_paths = extract_baton.result;
+
+ filter_baton.paths = added_paths;
+ filter_baton.buffer = extract_baton.buffer;
+ SVN_ERR(svn_iter_apr_hash(NULL, oldinfo,
+ filter_mergeinfo_paths,
+ &filter_baton, pool));
}
+ else
+ normalized_paths = apr_hash_make(pool);
+
+ verify_baton.path = path;
+ verify_baton.normalized_paths = normalized_paths;
+ verify_baton.buffer = extract_baton.buffer;
+ verify_baton.notify_func = notify_func;
+ verify_baton.notify_baton = notify_baton;
+ SVN_ERR(svn_iter_apr_hash(NULL, added_paths,
+ verify_mergeinfo_normalization,
+ &verify_baton, pool));
+
return SVN_NO_ERROR;
}
@@ -1047,18 +1164,18 @@ dump_node(struct edit_baton *eb,
SVN_PROP_MERGEINFO);
if (mergeinfo_str)
{
- svn_mergeinfo_t mergeinfo;
- struct check_mergeinfo_normalization_baton check_baton;
- check_baton.path = path;
- check_baton.normalized = apr_hash_make(pool);
- svn_membuf__create(&check_baton.buffer, 0, pool);
- check_baton.notify_func = eb->notify_func;
- check_baton.notify_baton = eb->notify_baton;
- SVN_ERR(svn_mergeinfo_parse(&mergeinfo,
- mergeinfo_str->data, pool));
- SVN_ERR(svn_iter_apr_hash(NULL, mergeinfo,
- check_mergeinfo_normalization,
- &check_baton, pool));
+ svn_string_t *oldinfo_str = NULL;
+ if (compare_root)
+ {
+ SVN_ERR(svn_fs_node_proplist(&oldhash,
+ compare_root, compare_path,
+ pool));
+ oldinfo_str = svn_hash_gets(oldhash, SVN_PROP_MERGEINFO);
+ }
+ SVN_ERR(check_mergeinfo_normalization(
+ path, mergeinfo_str->data,
+ (oldinfo_str ? oldinfo_str->data : NULL),
+ eb->notify_func, eb->notify_baton, pool));
}
}
@@ -1066,8 +1183,9 @@ dump_node(struct edit_baton *eb,
{
/* Fetch the old property hash to diff against and output a header
saying that our property contents are a delta. */
- SVN_ERR(svn_fs_node_proplist(&oldhash, compare_root, compare_path,
- pool));
+ if (!oldhash) /* May have been set for normalization check */
+ SVN_ERR(svn_fs_node_proplist(&oldhash, compare_root, compare_path,
+ pool));
SVN_ERR(svn_stream_puts(eb->stream,
SVN_REPOS_DUMPFILE_PROP_DELTA ": true\n"));
}
@@ -1257,7 +1375,7 @@ add_directory(const char *path,
if (!val && eb->verify && eb->check_ucs_norm && eb->notify_func)
{
pb->check_name_collision = TRUE;
- SVN_ERR(check_ucs_normalization(
+ SVN_ERR(check_path_normalization(
path, svn_node_dir,
eb->notify_func, eb->notify_baton, pool));
}
@@ -1366,7 +1484,7 @@ add_file(const char *path,
if (!val && eb->verify && eb->check_ucs_norm && eb->notify_func)
{
pb->check_name_collision = TRUE;
- SVN_ERR(check_ucs_normalization(
+ SVN_ERR(check_path_normalization(
path, svn_node_file,
eb->notify_func, eb->notify_baton, pool));
}
@@ -1960,40 +2078,38 @@ struct check_name_collision_baton
Unicode character representaiton. */
static svn_error_t *
check_name_collision(void *baton, const void *key, apr_ssize_t klen,
- void *val, apr_pool_t *pool)
+ void *val, apr_pool_t *iterpool)
{
- static const char unique[] = "unique";
- static const char collision[] = "collision";
-
- struct check_name_collision_baton *const check_baton = baton;
+ struct check_name_collision_baton *const cb = baton;
const char *name;
const char *found;
- SVN_ERR(svn_utf__normalize(&name, key, klen, &check_baton->buffer));
+ SVN_ERR(svn_utf__normalize(&name, key, klen, &cb->buffer));
- found = svn_hash_gets(check_baton->normalized, name);
+ found = svn_hash_gets(cb->normalized, name);
if (!found)
- svn_hash_sets(check_baton->normalized,
- apr_pstrdup(pool, name), unique);
- else if (found == collision)
+ svn_hash_sets(cb->normalized, apr_pstrdup(cb->buffer.pool, name),
+ normalized_unique);
+ else if (found == normalized_collision)
/* Skip already reported collision */;
else
{
- struct dir_baton *const db = check_baton->dir_baton;
+ struct dir_baton *const db = cb->dir_baton;
struct edit_baton *const eb = db->edit_baton;
svn_repos_notify_t *notify;
const char* normpath;
- svn_hash_sets(check_baton->normalized,
- apr_pstrdup(pool, name), collision);
+ svn_hash_sets(cb->normalized, apr_pstrdup(cb->buffer.pool, name),
+ normalized_collision);
+
SVN_ERR(svn_utf__normalize(
- &normpath, svn_relpath_join(db->path, name, pool),
- SVN_UTF__UNKNOWN_LENGTH, &check_baton->buffer));
- notify = svn_repos_notify_create(svn_repos_notify_warning, pool);
+ &normpath, svn_relpath_join(db->path, name, iterpool),
+ SVN_UTF__UNKNOWN_LENGTH, &cb->buffer));
+ notify = svn_repos_notify_create(svn_repos_notify_warning, iterpool);
notify->warning = svn_repos_notify_warning_name_collision;
notify->warning_str = apr_psprintf(
- pool, _("Duplicate representation of path '%s'"), normpath);
- eb->notify_func(eb->notify_baton, notify, pool);
+ iterpool, _("Duplicate representation of path '%s'"), normpath);
+ eb->notify_func(eb->notify_baton, notify, iterpool);
}
return SVN_NO_ERROR;
}
Modified: subversion/branches/log-addressing/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_repos/fs-wrap.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_repos/fs-wrap.c Sun Dec 1 19:37:30 2013
@@ -67,7 +67,9 @@ svn_repos_fs_commit_txn(const char **con
SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
SVN_ERR(svn_repos__hooks_pre_commit(repos, hooks_env, txn_name, pool));
- /* Remove any ephemeral transaction properties. */
+ /* Remove any ephemeral transaction properties. If the commit fails
+ we will attempt to restore the properties but if that fails, or
+ the process is killed, the properties will be lost. */
SVN_ERR(svn_fs_txn_proplist(&props, txn, pool));
iterpool = svn_pool_create(pool);
for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
@@ -86,9 +88,27 @@ svn_repos_fs_commit_txn(const char **con
svn_pool_destroy(iterpool);
/* Commit. */
- err = svn_fs_commit_txn(conflict_p, new_rev, txn, pool);
+ err = svn_fs_commit_txn2(conflict_p, new_rev, txn, TRUE, pool);
if (! SVN_IS_VALID_REVNUM(*new_rev))
- return err;
+ {
+ /* The commit failed, try to restore the ephemeral properties. */
+ iterpool = svn_pool_create(pool);
+ for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
+ {
+ const void *key;
+ void *val;
+ apr_hash_this(hi, &key, NULL, &val);
+
+ svn_pool_clear(iterpool);
+
+ if (strncmp(key, SVN_PROP_TXN_PREFIX,
+ (sizeof(SVN_PROP_TXN_PREFIX) - 1)) == 0)
+ svn_error_clear(svn_fs_change_txn_prop(txn, key, val, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+
+ return err;
+ }
/* Run post-commit hooks. */
if ((err2 = svn_repos__hooks_post_commit(repos, hooks_env,
Modified: subversion/branches/log-addressing/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/config_file.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/config_file.c Sun Dec 1 19:37:30 2013
@@ -412,7 +412,7 @@ svn_config__sys_config_path(const char *
#ifdef WIN32
{
const char *folder;
- SVN_ERR(svn_config__win_config_path(&folder, TRUE, pool));
+ SVN_ERR(svn_config__win_config_path(&folder, TRUE, pool, pool));
*path_p = svn_dirent_join_many(pool, folder,
SVN_CONFIG__SUBDIRECTORY, fname,
SVN_VA_NULL);
@@ -1370,7 +1370,11 @@ svn_config_get_user_config_path(const ch
#ifdef WIN32
{
const char *folder;
- SVN_ERR(svn_config__win_config_path(&folder, FALSE, pool));
+ SVN_ERR(svn_config__win_config_path(&folder, FALSE, pool, pool));
+
+ if (! folder)
+ return SVN_NO_ERROR;
+
*path = svn_dirent_join_many(pool, folder,
SVN_CONFIG__SUBDIRECTORY, fname, SVN_VA_NULL);
}
Modified: subversion/branches/log-addressing/subversion/libsvn_subr/config_impl.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/config_impl.h?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/config_impl.h (original)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/config_impl.h Sun Dec 1 19:37:30 2013
@@ -96,8 +96,9 @@ svn_error_t *svn_config__parse_stream(sv
#ifdef WIN32
/* Get the common or user-specific AppData folder */
svn_error_t *svn_config__win_config_path(const char **folder,
- int system_path,
- apr_pool_t *pool);
+ svn_boolean_t system_path,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool);
/* Read sections and options from the Windows Registry. */
svn_error_t *svn_config__parse_registry(svn_config_t *cfg,
Modified: subversion/branches/log-addressing/subversion/libsvn_subr/config_win.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/config_win.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/config_win.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/config_win.c Sun Dec 1 19:37:30 2013
@@ -46,8 +46,12 @@
#include "svn_utf.h"
#include "private/svn_utf_private.h"
+#include "config_impl.h"
+
svn_error_t *
-svn_config__win_config_path(const char **folder, int system_path,
+svn_config__win_config_path(const char **folder,
+ svn_boolean_t system_path,
+ apr_pool_t *scratch_pool,
apr_pool_t *result_pool)
{
/* ### Adding CSIDL_FLAG_CREATE here, because those folders really
@@ -57,6 +61,30 @@ svn_config__win_config_path(const char *
| CSIDL_FLAG_CREATE);
WCHAR folder_ucs2[MAX_PATH];
+ const char *folder_utf8;
+
+ if (! system_path)
+ {
+ HKEY hkey_tmp;
+
+ /* Verify if we actually have a *per user* profile to read from */
+ if (ERROR_SUCCESS == RegOpenCurrentUser(KEY_SET_VALUE, &hkey_tmp))
+ RegCloseKey(hkey_tmp); /* We have a profile */
+ else
+ {
+ /* The user is not properly logged in. (Most likely we are running
+ in a service process). In this case Windows will return a default
+ read only 'roaming profile' directory, which we assume to be
+ writable. We will then spend many seconds trying to create a
+ configuration and then fail, because we are not allowed to write
+ there, but the retry loop in io.c doesn't know that.
+
+ We just answer that there is no user configuration directory. */
+
+ *folder = NULL;
+ return SVN_NO_ERROR;
+ }
+ }
if (S_OK != SHGetFolderPathW(NULL, csidl, NULL, SHGFP_TYPE_CURRENT,
folder_ucs2))
@@ -65,16 +93,17 @@ svn_config__win_config_path(const char *
? "Can't determine the system config path"
: "Can't determine the user's config path"));
- return svn_error_trace(svn_utf__win32_utf16_to_utf8(folder, folder_ucs2,
- NULL, result_pool));
+ SVN_ERR(svn_utf__win32_utf16_to_utf8(&folder_utf8, folder_ucs2,
+ NULL, scratch_pool));
+ *folder = svn_dirent_internal_style(folder_utf8, result_pool);
+
+ return SVN_NO_ERROR;
}
-#include "config_impl.h"
-/* ### These constants are insanely large, but (a) we want to avoid
- reallocating strings if possible, and (b) the realloc logic might
- not actually work -- you never know with Win32 ... */
+/* ### These constants are insanely large, but we want to avoid
+ reallocating strings if possible. */
#define SVN_REG_DEFAULT_NAME_SIZE 2048
#define SVN_REG_DEFAULT_VALUE_SIZE 8192
Modified: subversion/branches/log-addressing/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/mergeinfo-cmd.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/mergeinfo-cmd.c Sun Dec 1 19:37:30 2013
@@ -275,7 +275,8 @@ mergeinfo_summary(
target_is_wc = (! svn_path_is_url(target_path_or_url))
&& (target_revision->kind == svn_opt_revision_unspecified
- || target_revision->kind == svn_opt_revision_working);
+ || target_revision->kind == svn_opt_revision_working
+ || target_revision->kind == svn_opt_revision_base);
SVN_ERR(svn_client_get_merging_summary(
&is_reintegration,
&yca_url, &yca_rev,
Modified: subversion/branches/log-addressing/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svnadmin/svnadmin.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/log-addressing/subversion/svnadmin/svnadmin.c Sun Dec 1 19:37:30 2013
@@ -805,6 +805,34 @@ subcommand_deltify(apr_getopt_t *os, voi
return SVN_NO_ERROR;
}
+/* Structure for errors encountered during 'svnadmin verify --keep-going'. */
+struct verification_error
+{
+ svn_revnum_t rev;
+ svn_error_t *err;
+};
+
+/* Pool cleanup function to clear an svn_error_t *. */
+static apr_status_t
+err_cleanup(void *data)
+{
+ svn_error_t *err = data;
+
+ svn_error_clear(err);
+
+ return APR_SUCCESS;
+}
+
+struct repos_notify_handler_baton {
+ /* Stream to write progress and other non-error output to. */
+ svn_stream_t *feedback_stream;
+
+ /* List of errors encountered during 'svnadmin verify --keep-going'. */
+ apr_array_header_t *error_summary;
+
+ /* Pool for data collected during notifications. */
+ apr_pool_t *result_pool;
+};
/* Implementation of svn_repos_notify_func_t to wrap the output to a
response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
@@ -813,7 +841,8 @@ repos_notify_handler(void *baton,
const svn_repos_notify_t *notify,
apr_pool_t *scratch_pool)
{
- svn_stream_t *feedback_stream = baton;
+ struct repos_notify_handler_baton *b = baton;
+ svn_stream_t *feedback_stream = b->feedback_stream;
switch (notify->action)
{
@@ -829,8 +858,22 @@ repos_notify_handler(void *baton,
_("* Error verifying revision %ld.\n"),
notify->revision));
if (notify->err)
- svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */,
- "svnadmin: ");
+ {
+ svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */,
+ "svnadmin: ");
+ if (b->error_summary && notify->revision != SVN_INVALID_REVNUM)
+ {
+ struct verification_error *verr;
+
+ verr = apr_palloc(b->result_pool, sizeof(*verr));
+ verr->rev = notify->revision;
+ verr->err = svn_error_dup(notify->err);
+ apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup,
+ apr_pool_cleanup_null);
+ APR_ARRAY_PUSH(b->error_summary,
+ struct verification_error *) = verr;
+ }
+ }
return;
case svn_repos_notify_dump_rev_end:
@@ -1065,7 +1108,7 @@ subcommand_dump(apr_getopt_t *os, void *
svn_stream_t *stdout_stream;
svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
svn_revnum_t youngest;
- svn_stream_t *progress_stream = NULL;
+ struct repos_notify_handler_baton notify_baton = { 0 };
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1099,12 +1142,12 @@ subcommand_dump(apr_getopt_t *os, void *
/* Progress feedback goes to STDERR, unless they asked to suppress it. */
if (! opt_state->quiet)
- progress_stream = recode_stream_create(stderr, pool);
+ notify_baton.feedback_stream = recode_stream_create(stderr, pool);
SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
opt_state->incremental, opt_state->use_deltas,
!opt_state->quiet ? repos_notify_handler : NULL,
- progress_stream, check_cancel, NULL, pool));
+ ¬ify_baton, check_cancel, NULL, pool));
return SVN_NO_ERROR;
}
@@ -1251,7 +1294,8 @@ subcommand_load(apr_getopt_t *os, void *
struct svnadmin_opt_state *opt_state = baton;
svn_repos_t *repos;
svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
- svn_stream_t *stdin_stream, *stdout_stream = NULL;
+ svn_stream_t *stdin_stream;
+ struct repos_notify_handler_baton notify_baton = { 0 };
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1285,7 +1329,7 @@ subcommand_load(apr_getopt_t *os, void *
/* Progress feedback goes to STDOUT, unless they asked to suppress it. */
if (! opt_state->quiet)
- stdout_stream = recode_stream_create(stdout, pool);
+ notify_baton.feedback_stream = recode_stream_create(stdout, pool);
err = svn_repos_load_fs4(repos, stdin_stream, lower, upper,
opt_state->uuid_action, opt_state->parent_dir,
@@ -1293,7 +1337,7 @@ subcommand_load(apr_getopt_t *os, void *
opt_state->use_post_commit_hook,
!opt_state->bypass_prop_validation,
opt_state->quiet ? NULL : repos_notify_handler,
- stdout_stream, check_cancel, NULL, pool);
+ ¬ify_baton, check_cancel, NULL, pool);
if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
return svn_error_quick_wrap(err,
_("Invalid property value found in "
@@ -1340,12 +1384,12 @@ subcommand_recover(apr_getopt_t *os, voi
svn_repos_t *repos;
svn_error_t *err;
struct svnadmin_opt_state *opt_state = baton;
- svn_stream_t *stdout_stream;
+ struct repos_notify_handler_baton notify_baton = { 0 };
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
- SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+ SVN_ERR(svn_stream_for_stdout(¬ify_baton.feedback_stream, pool));
/* Restore default signal handlers until after we have acquired the
* exclusive lock so that the user interrupt before we actually
@@ -1353,7 +1397,7 @@ subcommand_recover(apr_getopt_t *os, voi
setup_cancellation_signals(SIG_DFL);
err = svn_repos_recover4(opt_state->repository_path, TRUE,
- repos_notify_handler, stdout_stream,
+ repos_notify_handler, ¬ify_baton,
check_cancel, NULL, pool);
if (err)
{
@@ -1371,7 +1415,7 @@ subcommand_recover(apr_getopt_t *os, voi
" another process has it open?\n")));
SVN_ERR(svn_cmdline_fflush(stdout));
SVN_ERR(svn_repos_recover4(opt_state->repository_path, FALSE,
- repos_notify_handler, stdout_stream,
+ repos_notify_handler, ¬ify_baton,
check_cancel, NULL, pool));
}
@@ -1626,7 +1670,7 @@ subcommand_pack(apr_getopt_t *os, void *
{
struct svnadmin_opt_state *opt_state = baton;
svn_repos_t *repos;
- svn_stream_t *progress_stream = NULL;
+ struct repos_notify_handler_baton notify_baton = { 0 };
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1635,11 +1679,11 @@ subcommand_pack(apr_getopt_t *os, void *
/* Progress feedback goes to STDOUT, unless they asked to suppress it. */
if (! opt_state->quiet)
- progress_stream = recode_stream_create(stdout, pool);
+ notify_baton.feedback_stream = recode_stream_create(stdout, pool);
return svn_error_trace(
svn_repos_fs_pack2(repos, !opt_state->quiet ? repos_notify_handler : NULL,
- progress_stream, check_cancel, NULL, pool));
+ ¬ify_baton, check_cancel, NULL, pool));
}
@@ -1651,7 +1695,8 @@ subcommand_verify(apr_getopt_t *os, void
svn_repos_t *repos;
svn_fs_t *fs;
svn_revnum_t youngest, lower, upper;
- svn_stream_t *progress_stream = NULL;
+ struct repos_notify_handler_baton notify_baton = { 0 };
+ svn_error_t *verify_err;
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1696,15 +1741,79 @@ subcommand_verify(apr_getopt_t *os, void
}
if (! opt_state->quiet)
- progress_stream = recode_stream_create(stdout, pool);
+ notify_baton.feedback_stream = recode_stream_create(stdout, pool);
- return svn_error_trace(svn_repos_verify_fs3(repos, lower, upper,
- opt_state->keep_going,
- opt_state->check_ucs_norm,
- !opt_state->quiet
- ? repos_notify_handler : NULL,
- progress_stream, check_cancel,
- NULL, pool));
+ if (opt_state->keep_going)
+ notify_baton.error_summary =
+ apr_array_make(pool, 0, sizeof(struct verification_error *));
+
+ notify_baton.result_pool = pool;
+
+ verify_err = svn_repos_verify_fs3(repos, lower, upper,
+ opt_state->keep_going,
+ opt_state->check_ucs_norm,
+ !opt_state->quiet
+ ? repos_notify_handler : NULL,
+ ¬ify_baton, check_cancel,
+ NULL, pool);
+
+ /* Show the --keep-going error summary. */
+ if (opt_state->keep_going && notify_baton.error_summary->nelts > 0)
+ {
+ int rev_maxlength;
+ svn_revnum_t end_revnum;
+ apr_pool_t *iterpool;
+ int i;
+
+ svn_error_clear(
+ svn_stream_puts(notify_baton.feedback_stream,
+ _("\n-----Summary of corrupt revisions-----\n")));
+
+ /* The standard column width for the revision number is 6 characters.
+ If the revision number can potentially be larger (i.e. if end_revnum
+ is larger than 1000000), we increase the column width as needed. */
+ rev_maxlength = 6;
+ end_revnum = APR_ARRAY_IDX(notify_baton.error_summary,
+ notify_baton.error_summary->nelts - 1,
+ struct verification_error *)->rev;
+ while (end_revnum >= 1000000)
+ {
+ rev_maxlength++;
+ end_revnum = end_revnum / 10;
+ }
+
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < notify_baton.error_summary->nelts; i++)
+ {
+ struct verification_error *verr;
+ svn_error_t *err;
+ const char *rev_str;
+
+ svn_pool_clear(iterpool);
+
+ verr = APR_ARRAY_IDX(notify_baton.error_summary, i,
+ struct verification_error *);
+ rev_str = apr_psprintf(iterpool, "r%ld", verr->rev);
+ rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str);
+ for (err = svn_error_purge_tracing(verr->err);
+ err != SVN_NO_ERROR; err = err->child)
+ {
+ char buf[512];
+ const char *message;
+
+ message = svn_err_best_message(err, buf, sizeof(buf));
+ svn_error_clear(svn_stream_printf(notify_baton.feedback_stream,
+ iterpool,
+ "%s: E%06d: %s\n",
+ rev_str, err->apr_err,
+ message));
+ }
+ }
+
+ svn_pool_destroy(iterpool);
+ }
+
+ return svn_error_trace(verify_err);
}
/* This implements `svn_opt_subcommand_t'. */
@@ -2091,18 +2200,18 @@ subcommand_upgrade(apr_getopt_t *os, voi
{
svn_error_t *err;
struct svnadmin_opt_state *opt_state = baton;
- svn_stream_t *stdout_stream;
+ struct repos_notify_handler_baton notify_baton = { 0 };
/* Expect no more arguments. */
SVN_ERR(parse_args(NULL, os, 0, 0, pool));
- SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+ SVN_ERR(svn_stream_for_stdout(¬ify_baton.feedback_stream, pool));
/* Restore default signal handlers. */
setup_cancellation_signals(SIG_DFL);
err = svn_repos_upgrade2(opt_state->repository_path, TRUE,
- repos_notify_handler, stdout_stream, pool);
+ repos_notify_handler, ¬ify_baton, pool);
if (err)
{
if (APR_STATUS_IS_EAGAIN(err->apr_err))
@@ -2120,7 +2229,7 @@ subcommand_upgrade(apr_getopt_t *os, voi
" another process has it open?\n")));
SVN_ERR(svn_cmdline_fflush(stdout));
SVN_ERR(svn_repos_upgrade2(opt_state->repository_path, FALSE,
- repos_notify_handler, stdout_stream,
+ repos_notify_handler, ¬ify_baton,
pool));
}
else if (err->apr_err == SVN_ERR_FS_UNSUPPORTED_UPGRADE)
Modified: subversion/branches/log-addressing/subversion/tests/cmdline/mergeinfo_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/cmdline/mergeinfo_tests.py?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/cmdline/mergeinfo_tests.py (original)
+++ subversion/branches/log-addressing/subversion/tests/cmdline/mergeinfo_tests.py Sun Dec 1 19:37:30 2013
@@ -803,6 +803,20 @@ def mergeinfo_log(sbox):
'--log', sbox.repo_url + '/A',
sbox.ospath('A2'))
+@SkipUnless(server_has_mergeinfo)
+@Issue(4301)
+def mergeinfo_local_move(sbox):
+ "'mergeinfo' on a locally moved path"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_move('A', 'A2')
+ svntest.actions.run_and_verify_svn(None,
+ None, [],
+ 'mergeinfo', sbox.repo_url + '/A',
+ sbox.ospath('A2'))
+
########################################################################
# Run the tests
@@ -822,6 +836,7 @@ test_list = [ None,
natural_history_is_not_eligible_nor_merged,
noninheritable_mergeinfo_not_always_eligible,
mergeinfo_log,
+ mergeinfo_local_move,
]
if __name__ == '__main__':
Modified: subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests.py?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests.py Sun Dec 1 19:37:30 2013
@@ -1964,21 +1964,26 @@ def verify_keep_going(sbox):
"--keep-going",
sbox.repo_dir)
- if (svntest.main.options.server_minor_version < 9):
- exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
- ".*Verified revision 0.",
- ".*Verified revision 1.",
- ".*Error verifying revision 2.",
- ".*Error verifying revision 3."])
- exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*",
- "svnadmin: E165011:.*"], False)
- else:
+ if svntest.main.is_fs_log_addressing():
exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0",
".*Verified revision 0.",
".*Verified revision 1.",
".*Verified revision 2.",
".*Verified revision 3."])
exp_err = svntest.verify.RegexListOutput(["svnadmin: E165011:.*"], False)
+ else:
+ exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
+ ".*Verified revision 0.",
+ ".*Verified revision 1.",
+ ".*Error verifying revision 2.",
+ ".*Error verifying revision 3.",
+ ".*",
+ ".*Summary.*",
+ ".*r2: E160004:.*",
+ ".*r3: E160004:.*",
+ ".*r3: E160004:.*"])
+ exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*",
+ "svnadmin: E165011:.*"], False)
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
output, errput, exp_out, exp_err):
@@ -2095,10 +2100,28 @@ def verify_invalid_path_changes(sbox):
".*Error verifying revision 16.",
".*Verified revision 17.",
".*Error verifying revision 18.",
- ".*Verified revision 19."])
+ ".*Verified revision 19.",
+ ".*",
+ ".*Summary.*",
+ ".*r2: E160020:.*",
+ ".*r2: E160020:.*",
+ ".*r4: E160013:.*",
+ ".*r6: E160013:.*",
+ ".*r6: E160013:.*",
+ ".*r10: E160013:.*",
+ ".*r10: E160013:.*",
+ ".*r12: E145001:.*",
+ ".*r12: E145001:.*",
+ ".*r14: E160013:.*",
+ ".*r14: E160013:.*",
+ ".*r16: E145001:.*",
+ ".*r16: E145001:.*",
+ ".*r18: E160013:.*",
+ ".*r18: E160013:.*"])
exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*",
- "svnadmin: E165011:.*"], False)
+ "svnadmin: E145001:.*",
+ "svnadmin: E160013:.*"], False)
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
@@ -2108,15 +2131,17 @@ def verify_invalid_path_changes(sbox):
exit_code, output, errput = svntest.main.run_svnadmin("verify",
sbox.repo_dir)
- if repo_format(sbox) < 7:
- exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
- ".*Verified revision 0.",
- ".*Verified revision 1.",
- ".*Error verifying revision 2."])
- else:
+ if svntest.main.is_fs_log_addressing():
exp_out = svntest.verify.RegexListOutput([first_line])
exp_err = svntest.verify.RegexListOutput(["svnadmin: E160058:.*",
"svnadmin: E165011:.*"], False)
+ else:
+ exp_out = svntest.verify.RegexListOutput([".*Verifying repository metadata",
+ ".*Verified revision 0.",
+ ".*Verified revision 1.",
+ ".*Error verifying revision 2."])
+ exp_err = svntest.verify.RegexListOutput(["svnadmin: E160020:.*",
+ "svnadmin: E165011:.*"], False)
if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
output, errput, exp_out, exp_err):
@@ -2169,7 +2194,8 @@ def verify_denormalized_names(sbox):
"WARNING 0x0006: Duplicate representation of path '/Q/.*lpha'"
# A/{Eacute}
" in svn:mergeinfo property of 'A/.*'",
- ".*Verified revision 6."]
+ ".*Verified revision 6.",
+ ".*Verified revision 7."]
# The BDB backend doesn't do global metadata verification.
if not svntest.main.is_fs_type_bdb():
@@ -2179,11 +2205,11 @@ def verify_denormalized_names(sbox):
expected_output_regex_list.insert(0, ".* Verifying metadata at revision 0 ...")
exp_out = svntest.verify.RegexListOutput(expected_output_regex_list)
+ exp_err = svntest.verify.ExpectedOutput([])
- if svntest.verify.verify_outputs(
- "Unexpected error while running 'svnadmin verify'.",
- output, errput, exp_out, None):
- raise svntest.Failure
+ svntest.verify.verify_outputs(
+ "Unexpected error while running 'svnadmin verify'.",
+ output, errput, exp_out, exp_err)
########################################################################
Modified: subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests_data/normalization_check.dump
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests_data/normalization_check.dump?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests_data/normalization_check.dump [UTF-8] (original)
+++ subversion/branches/log-addressing/subversion/tests/cmdline/svnadmin_tests_data/normalization_check.dump [UTF-8] Sun Dec 1 19:37:30 2013
@@ -225,3 +225,35 @@ V 26
PROPS-END
+Revision-number: 7
+Prop-content-length: 130
+Content-length: 130
+
+K 10
+svn:author
+V 7
+jrandom
+K 8
+svn:date
+V 27
+2013-11-24T18:04:51.128158Z
+K 7
+svn:log
+V 25
+Update mergeinfo on A/É
+PROPS-END
+
+Node-path: A/É
+Node-kind: dir
+Node-action: change
+Prop-content-length: 64
+Content-length: 64
+
+K 13
+svn:mergeinfo
+V 29
+/Q/ålpha:71
+/Q/ålpha:69,71
+PROPS-END
+
+
Modified: subversion/branches/log-addressing/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/cmdline/svntest/main.py?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/log-addressing/subversion/tests/cmdline/svntest/main.py Sun Dec 1 19:37:30 2013
@@ -1337,7 +1337,7 @@ def is_fs_type_bdb():
return options.fs_type == 'bdb'
def is_fs_log_addressing():
- return options.fs_type == 'fsx' or \
+ return is_fs_type_fsx() or \
(is_fs_type_fsfs() and options.server_minor_version >= 9)
def is_os_windows():
Modified: subversion/branches/log-addressing/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/libsvn_fs/fs-test.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/log-addressing/subversion/tests/libsvn_fs/fs-test.c Sun Dec 1 19:37:30 2013
@@ -5076,6 +5076,76 @@ test_fs_info_format(const svn_test_opts_
}
static svn_error_t *
+commit_timestamp(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_string_t *date = svn_string_create("Yesterday", pool);
+ svn_revnum_t rev = 0;
+ apr_hash_t *proplist;
+ svn_string_t *svn_date;
+
+ SVN_ERR(svn_test__create_fs(&fs, "test-commit-timestamp",
+ opts, pool));
+
+ /* Commit with a specified svn:date. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "/foo", pool));
+ SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_DATE, date, pool));
+ SVN_ERR(svn_fs_commit_txn2(NULL, &rev, txn, FALSE, pool));
+
+ SVN_ERR(svn_fs_revision_proplist(&proplist, fs, rev, pool));
+ svn_date = apr_hash_get(proplist, SVN_PROP_REVISION_DATE,
+ APR_HASH_KEY_STRING);
+ SVN_TEST_ASSERT(svn_date && !strcmp(svn_date->data, date->data));
+
+ /* Commit that overwrites the specified svn:date. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "/bar", pool));
+ SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_DATE, date, pool));
+ SVN_ERR(svn_fs_commit_txn2(NULL, &rev, txn, TRUE, pool));
+
+ SVN_ERR(svn_fs_revision_proplist(&proplist, fs, rev, pool));
+ svn_date = apr_hash_get(proplist, SVN_PROP_REVISION_DATE,
+ APR_HASH_KEY_STRING);
+ SVN_TEST_ASSERT(svn_date && strcmp(svn_date->data, date->data));
+
+ /* Commit with a missing svn:date. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "/zag", pool));
+ SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_DATE, NULL, pool));
+ SVN_ERR(svn_fs_txn_prop(&svn_date, txn, SVN_PROP_REVISION_DATE, pool));
+ SVN_TEST_ASSERT(!svn_date);
+ SVN_ERR(svn_fs_commit_txn2(NULL, &rev, txn, FALSE, pool));
+
+ SVN_ERR(svn_fs_revision_proplist(&proplist, fs, rev, pool));
+ svn_date = apr_hash_get(proplist, SVN_PROP_REVISION_DATE,
+ APR_HASH_KEY_STRING);
+ SVN_TEST_ASSERT(!svn_date);
+
+ /* Commit that overwites a missing svn:date. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "/zig", pool));
+ SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_DATE, NULL, pool));
+ SVN_ERR(svn_fs_txn_prop(&svn_date, txn, SVN_PROP_REVISION_DATE, pool));
+ SVN_TEST_ASSERT(!svn_date);
+ SVN_ERR(svn_fs_commit_txn2(NULL, &rev, txn, TRUE, pool));
+
+ SVN_ERR(svn_fs_revision_proplist(&proplist, fs, rev, pool));
+ svn_date = apr_hash_get(proplist, SVN_PROP_REVISION_DATE,
+ APR_HASH_KEY_STRING);
+ SVN_TEST_ASSERT(svn_date);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
test_compat_version(const svn_test_opts_t *opts,
apr_pool_t *pool)
{
@@ -5217,6 +5287,8 @@ struct svn_test_descriptor_t test_funcs[
"filenames with trailing \\n might be rejected"),
SVN_TEST_OPTS_PASS(test_fs_info_format,
"test svn_fs_info_format"),
+ SVN_TEST_OPTS_PASS(commit_timestamp,
+ "commit timestamp"),
SVN_TEST_OPTS_PASS(test_compat_version,
"test svn_fs__compatible_version"),
SVN_TEST_NULL
Propchange: subversion/branches/log-addressing/subversion/tests/libsvn_fs_x/
------------------------------------------------------------------------------
Merged /subversion/trunk/subversion/tests/libsvn_fs_x:r1545955-1546835
Merged /subversion/branches/verify-keep-going/subversion/tests/libsvn_fs_x:r1546002-1546110
Merged /subversion/branches/fsfs-improvements/subversion/tests/libsvn_fs_x:r1545956-1546837
Modified: subversion/branches/log-addressing/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/libsvn_repos/repos-test.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/log-addressing/subversion/tests/libsvn_repos/repos-test.c Sun Dec 1 19:37:30 2013
@@ -3545,7 +3545,7 @@ test_repos_fs_type(const svn_test_opts_t
/* The test table. */
-int svn_test_max_threads = 4;
+int svn_test_max_threads = 2;
struct svn_test_descriptor_t test_funcs[] =
{
Modified: subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c (original)
+++ subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c Sun Dec 1 19:37:30 2013
@@ -303,5 +303,7 @@ struct svn_test_descriptor_t test_funcs[
"zero checksum cross-type matching"),
SVN_TEST_OPTS_PASS(zlib_expansion_test,
"zlib expansion test (zlib regression)"),
+ SVN_TEST_PASS2(zero_cross_match,
+ "zero checksum cross-type matching"),
SVN_TEST_NULL
};
Modified: subversion/branches/log-addressing/subversion/tests/svn_test_main.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/svn_test_main.c?rev=1546842&r1=1546841&r2=1546842&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/svn_test_main.c (original)
+++ subversion/branches/log-addressing/subversion/tests/svn_test_main.c Sun Dec 1 19:37:30 2013
@@ -52,11 +52,8 @@
#include "svn_private_config.h"
-#if APR_HAS_THREADS && APR_VERSION_AT_LEAST(1,3,0)
-# include <apr_thread_pool.h>
-# define HAVE_THREADPOOLS 1
-#else
-# define HAVE_THREADPOOLS 0
+#if APR_HAS_THREADS
+# include <apr_thread_proc.h>
#endif
/* Some Subversion test programs may want to parse options in the
@@ -420,7 +417,7 @@ do_test_num(const char *progname,
return skip_cleanup;
}
-#if HAVE_THREADPOOLS
+#if APR_HAS_THREADS
/* Per-test parameters used by test_thread */
typedef struct test_params_t
@@ -428,67 +425,86 @@ typedef struct test_params_t
/* Name of the application */
const char *progname;
- /* Number / index of the test to execute */
- int test_num;
+ /* Total number of tests to execute */
+ svn_atomic_t test_count;
/* Global test options as provided by main() */
svn_test_opts_t *opts;
- /* Thread-safe parent pool for the test-specific pool. We expect the
- test thread to create a sub-pool and destroy it after test completion. */
- apr_pool_t *pool;
-
/* Reference to the global failure flag. Set this if any test failed. */
- svn_atomic_t *got_error;
+ svn_atomic_t got_error;
- /* Reference to the global completed test counter. */
- svn_atomic_t *run_count;
+ /* Test to execute next. */
+ svn_atomic_t test_num;
} test_params_t;
/* Thread function similar to do_test_num() but with fewer options. We do
catch segfaults. All parameters are given as a test_params_t in DATA.
*/
static void * APR_THREAD_FUNC
-test_thread(apr_thread_t *tid, void *data)
+test_thread(apr_thread_t *thread, void *data)
{
svn_boolean_t skip, xfail, wimp;
svn_error_t *err = NULL;
const struct svn_test_descriptor_t *desc;
svn_boolean_t run_this_test; /* This test's mode matches DESC->MODE. */
test_params_t *params = data;
+ svn_atomic_t test_num;
- apr_pool_t *test_pool = svn_pool_create(params->pool);
+ apr_pool_t *pool
+ = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
- desc = &test_funcs[params->test_num];
- skip = desc->mode == svn_test_skip;
- xfail = desc->mode == svn_test_xfail;
- wimp = xfail && desc->wip;
- run_this_test = mode_filter == svn_test_all || mode_filter == desc->mode;
+ for (test_num = svn_atomic_inc(¶ms->test_num);
+ test_num <= params->test_count;
+ test_num = svn_atomic_inc(¶ms->test_num))
+ {
+ svn_pool_clear(pool);
+
+ desc = &test_funcs[test_num];
+ skip = desc->mode == svn_test_skip;
+ xfail = desc->mode == svn_test_xfail;
+ wimp = xfail && desc->wip;
+ run_this_test = mode_filter == svn_test_all
+ || mode_filter == desc->mode;
- /* Do test */
- if (skip || !run_this_test)
- ; /* pass */
- else if (desc->func2)
- err = (*desc->func2)(test_pool);
- else
- err = (*desc->func_opts)(params->opts, test_pool);
+ /* Do test */
+ if (skip || !run_this_test)
+ ; /* pass */
+ else if (desc->func2)
+ err = (*desc->func2)(pool);
+ else
+ err = (*desc->func_opts)(params->opts, pool);
- /* Write results to console */
- svn_error_clear(svn_mutex__lock(log_mutex));
- if (log_results(params->progname, params->test_num, FALSE, run_this_test,
- skip, xfail, wimp, err, desc->msg, desc))
- svn_atomic_set(params->got_error, TRUE);
- svn_error_clear(svn_mutex__unlock(log_mutex, NULL));
+ /* Write results to console */
+ svn_error_clear(svn_mutex__lock(log_mutex));
+ if (log_results(params->progname, test_num, FALSE, run_this_test,
+ skip, xfail, wimp, err, desc->msg, desc))
+ svn_atomic_set(¶ms->got_error, TRUE);
+ svn_error_clear(svn_mutex__unlock(log_mutex, NULL));
+ }
/* release all test memory */
- svn_pool_destroy(test_pool);
+ svn_pool_destroy(pool);
- /* one more test completed */
- svn_atomic_inc(params->run_count);
-
+ /* End thread explicitly to prevent APR_INCOMPLETE return codes in
+ apr_thread_join(). */
+ apr_thread_exit(thread, 0);
return NULL;
}
+/* Log an error with message MSG if the APR status of EXPR is not 0.
+ */
+#define CHECK_STATUS(expr,msg) \
+ do { \
+ apr_status_t rv = (expr); \
+ if (rv) \
+ { \
+ svn_error_t *svn_err__temp = svn_error_wrap_apr(rv, msg); \
+ svn_handle_error2(svn_err__temp, stdout, FALSE, "svn_tests: "); \
+ svn_error_clear(svn_err__temp); \
+ } \
+ } while (0);
+
/* Execute all ARRAY_SIZE tests concurrently using MAX_THREADS threads.
Pass PROGNAME and OPTS to the individual tests. Return TRUE if at least
one of the tests failed. Allocate all data in POOL.
@@ -502,56 +518,37 @@ do_tests_concurrently(const char *progna
svn_test_opts_t *opts,
apr_pool_t *pool)
{
- apr_thread_pool_t *threads;
- apr_status_t status;
- svn_atomic_t got_error = FALSE;
int i;
- svn_atomic_t run_count = 0;
-
- /* Create the thread pool. */
- status = apr_thread_pool_create(&threads, max_threads, max_threads, pool);
- if (status)
- {
- printf("apr_thread_pool_create() failed.\n");
- return TRUE;
- }
-
- /* Don't queue requests unless we reached the worker thread limit. */
- apr_thread_pool_threshold_set(threads, 0);
-
- /* Generate one task per test and queue them in the thread pool. */
- for (i = 1; i <= array_size; i++)
- {
- test_params_t *params = apr_pcalloc(pool, sizeof(*params));
- params->got_error = &got_error;
- params->opts = opts;
- params->pool = pool;
- params->progname = progname;
- params->test_num = i;
- params->run_count = &run_count;
+ apr_thread_t **threads;
- apr_thread_pool_push(threads, test_thread, params, 0, NULL);
+ /* Prepare thread parameters. */
+ test_params_t params;
+ params.got_error = FALSE;
+ params.opts = opts;
+ params.progname = progname;
+ params.test_num = 1;
+ params.test_count = array_size;
+
+ /* Start all threads. */
+ threads = apr_pcalloc(pool, max_threads * sizeof(*threads));
+ for (i = 0; i < max_threads; ++i)
+ {
+ CHECK_STATUS(apr_thread_create(&threads[i], NULL, test_thread, ¶ms,
+ pool),
+ "creating test thread failed.\n");
+ }
+
+ /* Wait for all tasks (tests) to complete. */
+ for (i = 0; i < max_threads; ++i)
+ {
+ apr_status_t result = 0;
+ CHECK_STATUS(apr_thread_join(&result, threads[i]),
+ "Waiting for test thread to finish failed.");
+ CHECK_STATUS(result,
+ "Test thread returned an error.");
}
-
- /* Wait for all tasks (tests) to complete. As it turns out, this is the
- variant with the least run-time overhead to the test threads. */
- while ( apr_thread_pool_tasks_count(threads)
- || apr_thread_pool_busy_count(threads))
- apr_thread_yield();
- /* For some unknown reason, cleaning POOL (TEST_POOL in main()) does not
- call the following reliably for all users. */
- apr_thread_pool_destroy(threads);
-
- /* Verify that we didn't skip any tasks. */
- if (run_count != array_size)
- {
- printf("Parallel test failure: only %d of %d tests executed.\n",
- (int)run_count, array_size);
- return TRUE;
- }
-
- return got_error != FALSE;
+ return params.got_error != FALSE;
}
#endif
@@ -798,7 +795,7 @@ main(int argc, const char *argv[])
}
break;
}
-#if HAVE_THREADPOOLS
+#if APR_HAS_THREADS
case parallel_opt:
parallel = TRUE;
break;
@@ -888,7 +885,7 @@ main(int argc, const char *argv[])
svn_pool_clear(cleanup_pool);
}
}
-#if HAVE_THREADPOOLS
+#if APR_HAS_THREADS
else
{
got_error = do_tests_concurrently(prog_name, array_size,