You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/03/16 11:10:22 UTC

svn commit: r1666947 [3/4] - in /subversion/branches/move-tracking-2: ./ subversion/ subversion/bindings/javahl/native/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_cli...

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/replay.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/replay.c Mon Mar 16 10:10:20 2015
@@ -427,10 +427,11 @@ replay_closed(svn_ra_serf__xml_estate_t
     {
       struct replay_node_t *node = ctx->current_node;
 
-      if (! node || ! node->file || ! node->stream)
+      if (! node || ! node->file)
         return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
 
-      SVN_ERR(svn_stream_close(node->stream));
+      if (node->stream)
+        SVN_ERR(svn_stream_close(node->stream));
 
       node->stream = NULL;
     }
@@ -565,10 +566,10 @@ svn_ra_serf__replay(svn_ra_session_t *ra
 
   SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
-  return svn_error_trace(
-              svn_ra_serf__error_on_status(handler->sline,
-                                           handler->path,
-                                           handler->location));
+  if (handler->sline.code != 200)
+    SVN_ERR(svn_ra_serf__unexpected_status(handler));
+
+  return SVN_NO_ERROR;
 }
 
 /* The maximum number of outstanding requests at any time. When this
@@ -646,9 +647,10 @@ svn_ra_serf__replay_range(svn_ra_session
   int active_reports = 0;
   const char *include_path;
   svn_boolean_t done;
+  apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
-                                       scratch_pool));
+                                       subpool));
 
   /* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
      aimed at the session URL.  But that's incorrect -- these reports
@@ -671,7 +673,7 @@ svn_ra_serf__replay_range(svn_ra_session
     {
       SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
                                              session->session_url.path,
-                                             session, scratch_pool));
+                                             session, subpool));
     }
   else
     {
@@ -689,7 +691,7 @@ svn_ra_serf__replay_range(svn_ra_session
         {
           struct revision_report_t *rev_ctx;
           svn_ra_serf__handler_t *handler;
-          apr_pool_t *rev_pool = svn_pool_create(scratch_pool);
+          apr_pool_t *rev_pool = svn_pool_create(subpool);
           svn_ra_serf__xml_context_t *xmlctx;
           const char *replay_target;
 
@@ -769,13 +771,23 @@ svn_ra_serf__replay_range(svn_ra_session
 
       /* Run the serf loop. */
       done = FALSE;
-      SVN_ERR(svn_ra_serf__context_run_wait(&done, session, scratch_pool));
+      {
+        svn_error_t *err = svn_ra_serf__context_run_wait(&done, session,
+                                                         subpool);
+
+        if (err)
+          {
+            svn_pool_destroy(subpool); /* Unregister all requests! */
+            return svn_error_trace(err);
+          }
+      }
 
       /* The done handler of reports decrements active_reports when a report
          is done. This same handler reports (fatal) report errors, so we can
          just loop here. */
     }
 
+  svn_pool_destroy(subpool);
   return SVN_NO_ERROR;
 }
 #undef MAX_OUTSTANDING_REQUESTS

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/serf.c Mon Mar 16 10:10:20 2015
@@ -600,7 +600,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
 #endif
 
   err = svn_ra_serf__exchange_capabilities(serf_sess, corrected_url,
-                                            result_pool, scratch_pool);
+                                           result_pool, scratch_pool);
 
   /* serf should produce a usable error code instead of APR_EGENERAL */
   if (err && err->apr_err == APR_EGENERAL)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/stat.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/stat.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/stat.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/stat.c Mon Mar 16 10:10:20 2015
@@ -472,6 +472,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
   svn_ra_serf__handler_t *props_handler = NULL;
   const char *path;
   struct get_dir_baton_t gdb;
+  svn_error_t *err = SVN_NO_ERROR;
 
   gdb.result_pool = result_pool;
   gdb.is_directory = FALSE;
@@ -542,10 +543,17 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
 
   if (dirent_handler)
     {
-      SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
+      err = svn_error_trace(
+              svn_ra_serf__context_run_wait(&dirent_handler->done,
                                             session,
                                             scratch_pool));
 
+      if (err)
+        {
+          svn_pool_clear(scratch_pool); /* Unregisters outstanding requests */
+          return err;
+        }
+
       if (gdb.supports_deadprop_count == svn_tristate_false
           && session->supports_deadprop_count == svn_tristate_unknown
           && dirent_fields & SVN_DIRENT_HAS_PROPS)
@@ -571,23 +579,27 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
 
   if (props_handler)
     {
-      SVN_ERR(svn_ra_serf__context_run_wait(&props_handler->done,
+      err = svn_error_trace(
+              svn_ra_serf__context_run_wait(&props_handler->done,
                                             session,
                                             scratch_pool));
     }
 
   /* And dirent again for the case when we had to send the request again */
-  if (dirent_handler)
+  if (! err && dirent_handler)
     {
-      SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
+      err = svn_error_trace(
+              svn_ra_serf__context_run_wait(&dirent_handler->done,
                                             session,
                                             scratch_pool));
     }
 
-  if (gdb.supports_deadprop_count != svn_tristate_unknown)
+  if (!err && gdb.supports_deadprop_count != svn_tristate_unknown)
     session->supports_deadprop_count = gdb.supports_deadprop_count;
 
-  svn_pool_destroy(scratch_pool);
+  svn_pool_destroy(scratch_pool); /* Unregisters outstanding requests */
+
+  SVN_ERR(err);
 
   if (!gdb.is_directory)
     return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/util.c Mon Mar 16 10:10:20 2015
@@ -947,6 +947,22 @@ svn_ra_serf__context_run_wait(svn_boolea
   return SVN_NO_ERROR;
 }
 
+/* Ensure that a handler is no longer scheduled on the connection.
+
+   Eventually serf will have a reliable way to cancel existing requests,
+   but currently it doesn't even have a way to relyable identify a request
+   after rescheduling, for auth reasons.
+
+   So the only thing we can do today is reset the connection, which
+   will cancel all outstanding requests and prepare the connection
+   for re-use.
+*/
+static void
+svn_ra_serf__unschedule_handler(svn_ra_serf__handler_t *handler)
+{
+  serf_connection_reset(handler->conn->conn);
+  handler->scheduled = FALSE;
+}
 
 svn_error_t *
 svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
@@ -960,6 +976,15 @@ svn_ra_serf__context_run_one(svn_ra_serf
   /* Wait until the response logic marks its DONE status.  */
   err = svn_ra_serf__context_run_wait(&handler->done, handler->session,
                                       scratch_pool);
+
+  if (handler->scheduled)
+    {
+      /* We reset the connection (breaking  pipelining, etc.), as
+         if we didn't the next data would still be handled by this handler,
+         which is done as far as our caller is concerned. */
+      svn_ra_serf__unschedule_handler(handler);
+    }
+
   return svn_error_trace(err);
 }
 
@@ -1453,7 +1478,13 @@ handle_response_cb(serf_request_t *reque
     {
       handler->discard_body = TRUE; /* Discard further data */
       handler->done = TRUE; /* Mark as done */
-      handler->scheduled = FALSE;
+      /* handler->scheduled is still TRUE, as we still expect data.
+         If we would return an error outer-status the connection
+         would have to be restarted. With scheduled still TRUE
+         destroying the handler's pool will still reset the
+         connection, avoiding the posibility of returning
+         an error for this handler when a new request is
+         scheduled. */
       outer_status = APR_EAGAIN; /* Exit context loop */
     }
 
@@ -1762,8 +1793,9 @@ svn_ra_serf__error_on_status(serf_status
         return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                                  _("'%s' path not found"), path);
       case 405:
-        return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE, NULL,
-                                 _("'%s' is out of date"), path);
+        return svn_error_createf(SVN_ERR_RA_DAV_METHOD_NOT_ALLOWED, NULL,
+                                 _("HTTP method is not allowed on '%s'"),
+                                 path);
       case 409:
         return svn_error_createf(SVN_ERR_FS_CONFLICT, NULL,
                                  _("'%s' conflicts"), path);
@@ -1802,9 +1834,10 @@ svn_error_t *
 svn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler)
 {
   /* Is it a standard error status? */
-  SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
-                                       handler->path,
-                                       handler->location));
+  if (handler->sline.code != 405)
+    SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
+                                         handler->path,
+                                         handler->location));
 
   switch (handler->sline.code)
     {
@@ -1817,6 +1850,11 @@ svn_ra_serf__unexpected_status(svn_ra_se
                                  _("Path '%s' already exists"),
                                  handler->path);
 
+      case 405:
+        return svn_error_createf(SVN_ERR_RA_DAV_METHOD_NOT_ALLOWED, NULL,
+                                 _("The HTTP method '%s' is not allowed"
+                                   " on '%s'"),
+                                 handler->method, handler->path);
       default:
         return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                  _("Unexpected HTTP status %d '%s' on '%s' "
@@ -1874,14 +1912,14 @@ response_done(serf_request_t *request,
    handlers registered in no freed memory.
 
    This fallback kills the connection for this case, which will make serf
-   unregister any*/
+   unregister any outstanding requests on it. */
 static apr_status_t
 handler_cleanup(void *baton)
 {
   svn_ra_serf__handler_t *handler = baton;
-  if (handler->scheduled && handler->conn && handler->conn->conn)
+  if (handler->scheduled)
     {
-      serf_connection_reset(handler->conn->conn);
+      svn_ra_serf__unschedule_handler(handler);
     }
 
   return APR_SUCCESS;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c Mon Mar 16 10:10:20 2015
@@ -1778,7 +1778,7 @@ perform_ra_svn_log(svn_error_t **outer_e
           - Except if the server sends more than a >= 1 limit top level items
           - Or when the callback reported a SVN_ERR_CEASE_INVOCATION
             in an earlier invocation. */
-      if (! (limit && (nest_level == 0) && (++nreceived > limit))
+      if (! ((limit > 0) && (nest_level == 0) && (++nreceived > limit))
           && ! *outer_error)
         {
           svn_error_t *err;
@@ -1806,7 +1806,7 @@ perform_ra_svn_log(svn_error_t **outer_e
                           SVN_PROP_REVISION_LOG, message);
 
           err = receiver(receiver_baton, log_entry, iterpool);
-          if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
+          if (svn_error_find_cause(err, SVN_ERR_CEASE_INVOCATION))
             {
               *outer_error = svn_error_trace(
                                 svn_error_compose_create(*outer_error, err));
@@ -1994,14 +1994,15 @@ static svn_error_t *ra_svn_get_locations
 }
 
 static svn_error_t *
-ra_svn_get_location_segments(svn_ra_session_t *session,
-                             const char *path,
-                             svn_revnum_t peg_revision,
-                             svn_revnum_t start_rev,
-                             svn_revnum_t end_rev,
-                             svn_location_segment_receiver_t receiver,
-                             void *receiver_baton,
-                             apr_pool_t *pool)
+perform_get_location_segments(svn_error_t **outer_error,
+                              svn_ra_session_t *session,
+                              const char *path,
+                              svn_revnum_t peg_revision,
+                              svn_revnum_t start_rev,
+                              svn_revnum_t end_rev,
+                              svn_location_segment_receiver_t receiver,
+                              void *receiver_baton,
+                              apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -2048,7 +2049,17 @@ ra_svn_get_location_segments(svn_ra_sess
           segment->path = ret_path;
           segment->range_start = range_start;
           segment->range_end = range_end;
-          SVN_ERR(receiver(segment, receiver_baton, iterpool));
+
+          if (!*outer_error)
+            {
+              svn_error_t *err = svn_error_trace(receiver(segment, receiver_baton,
+                                                          iterpool));
+
+              if (svn_error_find_cause(err, SVN_ERR_CEASE_INVOCATION))
+                *outer_error = err;
+              else
+                SVN_ERR(err);
+            }
         }
     }
   svn_pool_destroy(iterpool);
@@ -2060,6 +2071,26 @@ ra_svn_get_location_segments(svn_ra_sess
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+ra_svn_get_location_segments(svn_ra_session_t *session,
+                             const char *path,
+                             svn_revnum_t peg_revision,
+                             svn_revnum_t start_rev,
+                             svn_revnum_t end_rev,
+                             svn_location_segment_receiver_t receiver,
+                             void *receiver_baton,
+                             apr_pool_t *pool)
+{
+  svn_error_t *outer_err = SVN_NO_ERROR;
+  svn_error_t *err;
+
+  err = svn_error_trace(
+            perform_get_location_segments(&outer_err, session, path,
+                                          peg_revision, start_rev, end_rev,
+                                          receiver, receiver_baton, pool));
+  return svn_error_compose_create(outer_err, err);
+}
+
 static svn_error_t *ra_svn_get_file_revs(svn_ra_session_t *session,
                                          const char *path,
                                          svn_revnum_t start, svn_revnum_t end,
@@ -2720,10 +2751,16 @@ ra_svn_replay_range(svn_ra_session_t *se
 
       SVN_ERR(svn_ra_svn__read_tuple(sess->conn, iterpool,
                                      "wl", &word, &list));
+
       if (strcmp(word, "revprops") != 0)
-        return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
-                                 _("Expected 'revprops', found '%s'"),
-                                 word);
+        {
+          if (strcmp(word, "failure") == 0)
+            SVN_ERR(svn_ra_svn__handle_failure_status(list, iterpool));
+
+          return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                                   _("Expected 'revprops', found '%s'"),
+                                   word);
+        }
 
       SVN_ERR(svn_ra_svn__parse_proplist(list, iterpool, &rev_props));
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c Mon Mar 16 10:10:20 2015
@@ -843,6 +843,14 @@ static svn_error_t *ra_svn_handle_close_
 {
   SVN_CMD_ERR(ds->editor->close_edit(ds->edit_baton, pool));
   ds->done = TRUE;
+#ifdef SVN_DEBUG
+  /* Before enabling this in non-maintainer mode:
+     *  Note that this code is used on both client *and* server */
+  if (apr_hash_count(ds->tokens) != 0)
+    return svn_error_create(
+              SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION, NULL,
+              _("Closing editor with directories or files open"));
+#endif
   if (ds->aborted)
     *ds->aborted = FALSE;
   return svn_ra_svn__write_cmd_response(conn, pool, "");

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/replay.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/replay.c Mon Mar 16 10:10:20 2015
@@ -555,10 +555,6 @@ path_driver_cb_func(void **dir_baton,
         return svn_error_create(SVN_ERR_FS_ALREADY_EXISTS, NULL,
                                 _("Root directory already exists."));
 
-      /* A NULL parent_baton will cause a segfault.  It should never be
-          NULL for non-root paths. */
-      SVN_ERR_ASSERT(parent_baton);
-
       /* Was this node copied? */
       SVN_ERR(fill_copyfrom(&copyfrom_root, &copyfrom_path, &copyfrom_rev,
                             &src_readable, root, change,
@@ -971,6 +967,11 @@ svn_repos_replay2(svn_fs_root_t *root,
   const char *repos_root = "";
   void *unlock_baton;
 
+  /* If we were not given a low water mark, assume that everything is there,
+     all the way back to revision 0. */
+  if (! SVN_IS_VALID_REVNUM(low_water_mark))
+    low_water_mark = 0;
+
   /* Special-case r0, which we know is an empty revision; if we don't
      special-case it we might end up trying to compare it to "r-1". */
   if (svn_fs_is_revision_root(root)
@@ -1493,7 +1494,7 @@ svn_repos__replay_ev2(svn_fs_root_t *roo
   svn_error_t *err = SVN_NO_ERROR;
   int i;
 
-  SVN_ERR_ASSERT(!svn_dirent_is_absolute(base_repos_relpath));
+  SVN_ERR_ASSERT(svn_relpath_is_canonical(base_repos_relpath));
 
   /* Special-case r0, which we know is an empty revision; if we don't
      special-case it we might end up trying to compare it to "r-1". */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c Mon Mar 16 10:10:20 2015
@@ -837,27 +837,32 @@ svn_repos_node_location_segments(svn_rep
 {
   svn_fs_t *fs = svn_repos_fs(repos);
   svn_stringbuf_t *current_path;
-  svn_revnum_t youngest_rev = SVN_INVALID_REVNUM, current_rev;
+  svn_revnum_t youngest_rev, current_rev;
   apr_pool_t *subpool;
 
+  SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
+
   /* No PEG_REVISION?  We'll use HEAD. */
   if (! SVN_IS_VALID_REVNUM(peg_revision))
-    {
-      SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
-      peg_revision = youngest_rev;
-    }
+    peg_revision = youngest_rev;
+
+  if (peg_revision > youngest_rev)
+    return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                             _("No such revision %ld"), peg_revision);
 
-  /* No START_REV?  We'll use HEAD (which we may have already fetched). */
+  /* No START_REV?  We'll use peg rev. */
   if (! SVN_IS_VALID_REVNUM(start_rev))
-    {
-      if (SVN_IS_VALID_REVNUM(youngest_rev))
-        start_rev = youngest_rev;
-      else
-        SVN_ERR(svn_fs_youngest_rev(&start_rev, fs, pool));
-    }
+    start_rev = peg_revision;
+  else if (start_rev > peg_revision)
+    return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                             _("No such revision %ld"), start_rev);
 
   /* No END_REV?  We'll use 0. */
-  end_rev = SVN_IS_VALID_REVNUM(end_rev) ? end_rev : 0;
+  if (! SVN_IS_VALID_REVNUM(end_rev))
+    end_rev = 0;
+  else if (end_rev > start_rev)
+    return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                             _("No such revision %ld"), end_rev);
 
   /* Are the revision properly ordered?  They better be -- the API
      demands it. */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c Mon Mar 16 10:10:20 2015
@@ -20,6 +20,7 @@
  * ====================================================================
  */
 
+#include <assert.h>
 #include <apr_time.h>
 #include "private/svn_atomic.h"
 
@@ -29,11 +30,20 @@
 #define SVN_ATOMIC_INIT_FAILED   2
 #define SVN_ATOMIC_INITIALIZED   3
 
-svn_error_t*
-svn_atomic__init_once(volatile svn_atomic_t *global_status,
-                      svn_error_t *(*init_func)(void*,apr_pool_t*),
-                      void *baton,
-                      apr_pool_t* pool)
+
+/*
+ * This is the actual atomic initialization driver.  The caller must
+ * provide either ERR_INIT_FUNC and ERR_P, or STR_INIT_FUNC and
+ * ERRSTR_P, but never both.
+ */
+static void
+init_once(svn_atomic__err_init_func_t err_init_func,
+          svn_error_t **err_p,
+          svn_atomic__str_init_func_t str_init_func,
+          const char **errstr_p,
+          volatile svn_atomic_t *global_status,
+          void *baton,
+          apr_pool_t* pool)
 {
   /* !! Don't use localizable strings in this function, because these
      !! might cause deadlocks. This function can be used to initialize
@@ -42,44 +52,94 @@ svn_atomic__init_once(volatile svn_atomi
   /* We have to call init_func exactly once.  Because APR
      doesn't have statically-initialized mutexes, we implement a poor
      man's spinlock using svn_atomic_cas. */
+
+  svn_error_t *err = SVN_NO_ERROR;
+  const char *errstr = NULL;
   svn_atomic_t status = svn_atomic_cas(global_status,
                                        SVN_ATOMIC_START_INIT,
                                        SVN_ATOMIC_UNINITIALIZED);
 
-  if (status == SVN_ATOMIC_UNINITIALIZED)
+#ifdef SVN_DEBUG
+  /* Check that the parameters are valid. */
+  assert(!err_init_func != !str_init_func);
+  assert(!err_init_func == !err_p);
+  assert(!str_init_func == !errstr_p);
+#endif /* SVN_DEBUG */
+
+  for (;;)
     {
-      svn_error_t *err = init_func(baton, pool);
-      if (err)
+      switch (status)
         {
-#if APR_HAS_THREADS
-          /* Tell other threads that the initialization failed. */
-          svn_atomic_cas(global_status,
-                         SVN_ATOMIC_INIT_FAILED,
-                         SVN_ATOMIC_START_INIT);
-#endif
-          return svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, err,
-                                  "Couldn't perform atomic initialization");
+        case SVN_ATOMIC_UNINITIALIZED:
+          if (err_init_func)
+            err = err_init_func(baton, pool);
+          else
+            errstr = str_init_func(baton);
+          if (err || errstr)
+            {
+              status = svn_atomic_cas(global_status,
+                                      SVN_ATOMIC_INIT_FAILED,
+                                      SVN_ATOMIC_START_INIT);
+            }
+          else
+            {
+              status = svn_atomic_cas(global_status,
+                                      SVN_ATOMIC_INITIALIZED,
+                                      SVN_ATOMIC_START_INIT);
+            }
+
+          /* Take another spin through the switch to report either
+             failure or success. */
+          continue;
+
+        case SVN_ATOMIC_START_INIT:
+          /* Wait for the init function to complete. */
+          apr_sleep(APR_USEC_PER_SEC / 1000);
+          status = svn_atomic_cas(global_status,
+                                  SVN_ATOMIC_UNINITIALIZED,
+                                  SVN_ATOMIC_UNINITIALIZED);
+          continue;
+
+        case SVN_ATOMIC_INIT_FAILED:
+          if (err_init_func)
+            *err_p = svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, err,
+                                      "Couldn't perform atomic initialization");
+          else
+            *errstr_p = errstr;
+          return;
+
+        case SVN_ATOMIC_INITIALIZED:
+          if (err_init_func)
+            *err_p = SVN_NO_ERROR;
+          else
+            *errstr_p = NULL;
+          return;
+
+        default:
+          /* Something went seriously wrong with the atomic operations. */
+          abort();
         }
-      svn_atomic_cas(global_status,
-                     SVN_ATOMIC_INITIALIZED,
-                     SVN_ATOMIC_START_INIT);
-    }
-#if APR_HAS_THREADS
-  /* Wait for whichever thread is performing initialization to finish. */
-  /* XXX FIXME: Should we have a maximum wait here, like we have in
-                the Windows file IO spinner? */
-  else while (status != SVN_ATOMIC_INITIALIZED)
-    {
-      if (status == SVN_ATOMIC_INIT_FAILED)
-        return svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, NULL,
-                                "Couldn't perform atomic initialization");
-
-      apr_sleep(APR_USEC_PER_SEC / 1000);
-      status = svn_atomic_cas(global_status,
-                              SVN_ATOMIC_UNINITIALIZED,
-                              SVN_ATOMIC_UNINITIALIZED);
     }
-#endif /* APR_HAS_THREADS */
+}
+
 
-  return SVN_NO_ERROR;
+svn_error_t *
+svn_atomic__init_once(volatile svn_atomic_t *global_status,
+                      svn_atomic__err_init_func_t err_init_func,
+                      void *baton,
+                      apr_pool_t* pool)
+{
+  svn_error_t *err;
+  init_once(err_init_func, &err, NULL, NULL, global_status, baton, pool);
+  return err;
+}
+
+const char *
+svn_atomic__init_once_no_error(volatile svn_atomic_t *global_status,
+                               svn_atomic__str_init_func_t str_init_func,
+                               void *baton)
+{
+  const char *errstr;
+  init_once(NULL, NULL, str_init_func, &errstr, global_status, baton, NULL);
+  return errstr;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c Mon Mar 16 10:10:20 2015
@@ -207,8 +207,7 @@ svn_auth_get_parameter(svn_auth_baton_t
   value = svn_hash_gets(auth_baton->slave_parameters, name);
 
   if (value)
-    return (value == &auth_NULL) ? NULL
-                                : value;
+    return (value == &auth_NULL ? NULL : value);
 
   return svn_hash_gets(auth_baton->parameters, name);
 }
@@ -354,7 +353,7 @@ svn_auth_next_credentials(void **credent
         {
           SVN_ERR(provider->vtable->first_credentials(
                       &creds, &(state->provider_iter_baton),
-                      provider->provider_baton, auth_baton->parameters,
+                      provider->provider_baton, state->parameters,
                       state->realmstring, auth_baton->pool));
           state->got_first = TRUE;
         }
@@ -392,19 +391,17 @@ svn_auth_save_credentials(svn_auth_iters
   svn_auth_provider_object_t *provider;
   svn_boolean_t save_succeeded = FALSE;
   const char *no_auth_cache;
-  svn_auth_baton_t *auth_baton;
   void *creds;
 
   if (! state || state->table->providers->nelts <= state->provider_idx)
     return SVN_NO_ERROR;
 
-  auth_baton = state->auth_baton;
   creds = svn_hash_gets(state->auth_baton->creds_cache, state->cache_key);
   if (! creds)
     return SVN_NO_ERROR;
 
   /* Do not save the creds if SVN_AUTH_PARAM_NO_AUTH_CACHE is set */
-  no_auth_cache = svn_hash_gets(auth_baton->parameters,
+  no_auth_cache = svn_hash_gets(state->parameters,
                                 SVN_AUTH_PARAM_NO_AUTH_CACHE);
   if (no_auth_cache)
     return SVN_NO_ERROR;
@@ -417,7 +414,7 @@ svn_auth_save_credentials(svn_auth_iters
     SVN_ERR(provider->vtable->save_credentials(&save_succeeded,
                                                creds,
                                                provider->provider_baton,
-                                               auth_baton->parameters,
+                                               state->parameters,
                                                state->realmstring,
                                                pool));
   if (save_succeeded)
@@ -433,7 +430,7 @@ svn_auth_save_credentials(svn_auth_iters
       if (provider->vtable->save_credentials)
         SVN_ERR(provider->vtable->save_credentials(&save_succeeded, creds,
                                                    provider->provider_baton,
-                                                   auth_baton->parameters,
+                                                   state->parameters,
                                                    state->realmstring,
                                                    pool));
 
@@ -768,12 +765,10 @@ svn_auth__make_session_auth(svn_auth_bat
   * "store-auth-creds = yes" -- they'll get the expected behaviour.
   */
 
-  if (svn_auth_get_parameter(ab,
-                              SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
+  if (svn_auth_get_parameter(ab, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
     store_passwords = FALSE;
 
-  if (svn_auth_get_parameter(ab,
-                              SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
+  if (svn_auth_get_parameter(ab, SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
     store_auth_creds = FALSE;
 
   /* All the svn_auth_set_parameter() calls below this not only affect the
@@ -858,8 +853,7 @@ svn_auth__make_session_auth(svn_auth_bat
 
   /* Save auth caching parameters in the auth parameter hash. */
   if (! store_passwords)
-    svn_auth_set_parameter(ab,
-                           SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
+    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
 
   svn_auth_set_parameter(ab,
                          SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
@@ -875,8 +869,7 @@ svn_auth__make_session_auth(svn_auth_bat
                          store_pp_plaintext);
 
   if (! store_auth_creds)
-    svn_auth_set_parameter(ab,
-                           SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
+    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
 
   if (server_group)
     svn_auth_set_parameter(ab,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/error.c Mon Mar 16 10:10:20 2015
@@ -59,11 +59,12 @@ static apr_threadkey_t *error_line_key =
 /* No-op destructor for apr_threadkey_private_create(). */
 static void null_threadkey_dtor(void *stuff) {}
 
-/* Handler for svn_atomic__init_once used by svn_error__locate to
-   initialize the thread-local error location storage.
-   This function will never return an error. */
-static svn_error_t *
-locate_init_once(void *ignored_baton, apr_pool_t *ignored_pool)
+/* Implements svn_atomic__str_init_func_t.
+   Callback used by svn_error__locate to initialize the thread-local
+   error location storage.  This function will never return an
+   error string. */
+static const char *
+locate_init_once(void *ignored_baton)
 {
   /* Strictly speaking, this is a memory leak, since we're creating an
      unmanaged, top-level pool and never destroying it.  We do this
@@ -86,7 +87,7 @@ locate_init_once(void *ignored_baton, ap
   if (status != APR_SUCCESS)
     error_file_key = error_line_key = NULL;
 
-  return SVN_NO_ERROR;
+  return NULL;
 }
 #  endif  /* APR_HAS_THREADS */
 
@@ -124,9 +125,7 @@ svn_error__locate(const char *file, long
 #ifdef SVN_DEBUG
 #  if APR_HAS_THREADS
   static volatile svn_atomic_t init_status = 0;
-  svn_error_clear(svn_atomic__init_once(&init_status,
-                                        locate_init_once,
-                                        NULL, NULL));
+  svn_atomic__init_once_no_error(&init_status, locate_init_once, NULL);
 
   if (error_file_key && error_line_key)
     {

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/utf8proc/utf8proc.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/utf8proc/utf8proc.h?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/utf8proc/utf8proc.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/utf8proc/utf8proc.h Mon Mar 16 10:10:20 2015
@@ -74,17 +74,17 @@
 # if _MSC_VER >= 1600
 #   include <stdint.h>
 # else
-    typedef signed char int8_t;
-    typedef unsigned char uint8_t;
-    typedef short int16_t;
-    typedef unsigned short uint16_t;
-    typedef int int32_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
 # endif
 # if _MSC_VER >= 1800
 #   include <stdbool.h>
 # else
-    typedef unsigned char bool;
-    enum {false, true};
+typedef unsigned char bool;
+enum {false, true};
 # endif
 # ifdef _WIN64
 #   define ssize_t __int64

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/update_editor.c Mon Mar 16 10:10:20 2015
@@ -1935,7 +1935,8 @@ add_directory(const char *path,
       SVN_ERR_ASSERT(conflicted);
       versioned_locally_and_present = FALSE; /* Tree conflict ACTUAL-only node */
     }
-  else if (status == svn_wc__db_status_normal)
+  else if (status == svn_wc__db_status_normal
+           || status == svn_wc__db_status_incomplete)
     {
       svn_boolean_t root;
 
@@ -2752,7 +2753,8 @@ close_directory(void *dir_baton,
                                     db->old_revision,
                                     db->new_repos_relpath,
                                     svn_node_dir, svn_node_dir,
-                                    db->parent_baton->deletion_conflicts
+                                    (db->parent_baton
+                                     && db->parent_baton->deletion_conflicts)
                                       ? svn_hash_gets(
                                             db->parent_baton->deletion_conflicts,
                                             db->name)
@@ -3118,7 +3120,8 @@ add_file(const char *path,
       SVN_ERR_ASSERT(conflicted);
       versioned_locally_and_present = FALSE; /* Tree conflict ACTUAL-only node */
     }
-  else if (status == svn_wc__db_status_normal)
+  else if (status == svn_wc__db_status_normal
+           || status == svn_wc__db_status_incomplete)
     {
       svn_boolean_t root;
 

Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/reports/inherited-props.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/reports/inherited-props.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_dav_svn/reports/inherited-props.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/reports/inherited-props.c Mon Mar 16 10:10:20 2015
@@ -61,6 +61,7 @@ dav_svn__get_inherited_props_report(cons
   int i;
   svn_revnum_t rev = SVN_INVALID_REVNUM;
   apr_pool_t *iterpool;
+  svn_node_kind_t kind;
 
   /* Sanity check. */
   if (!resource->info->repos_path)
@@ -114,6 +115,20 @@ dav_svn__get_inherited_props_report(cons
                                 "couldn't retrieve revision root",
                                 resource->pool);
 
+  serr = svn_fs_check_path(&kind, root, path, resource->pool);
+  if (!serr && kind == svn_node_none)
+    {
+      serr = svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                               "'%s' path not found", path);
+    }
+
+  if (serr)
+    {
+      derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, NULL,
+                                  resource->pool);
+      goto cleanup;
+    }
+
   serr = svn_repos_fs_get_inherited_props(&inherited_props, root, path, NULL,
                                           dav_svn__authz_read_func(&arb),
                                           &arb, resource->pool, iterpool);

Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c Mon Mar 16 10:10:20 2015
@@ -135,6 +135,7 @@ dav_svn__convert_err(svn_error_t *serr,
   switch (purged_serr->apr_err)
     {
     case SVN_ERR_FS_NOT_FOUND:
+    case SVN_ERR_FS_NO_SUCH_REVISION:
       status = HTTP_NOT_FOUND;
       break;
     case SVN_ERR_UNSUPPORTED_FEATURE:

Modified: subversion/branches/move-tracking-2/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/serve.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/serve.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/serve.c Mon Mar 16 10:10:20 2015
@@ -3296,6 +3296,7 @@ get_inherited_props(svn_ra_svn_conn_t *c
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
   authz_baton_t ab;
+  svn_node_kind_t node_kind;
 
   ab.server = b;
   ab.conn = conn;
@@ -3311,15 +3312,18 @@ get_inherited_props(svn_ra_svn_conn_t *c
   SVN_ERR(must_have_access(conn, iterpool, b, svn_authz_read,
                            full_path, FALSE));
 
-  if (!SVN_IS_VALID_REVNUM(rev))
-    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));
-
   SVN_ERR(log_command(b, conn, pool, "%s",
                       svn_log__get_inherited_props(full_path, rev,
                                                    iterpool)));
 
   /* Fetch the properties and a stream for the contents. */
   SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, iterpool));
+  SVN_CMD_ERR(svn_fs_check_path(&node_kind, root, full_path, pool));
+  if (node_kind == svn_node_none)
+    {
+      SVN_CMD_ERR(svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                    _("'%s' path not found"), full_path));
+    }
   SVN_CMD_ERR(get_props(NULL, &inherited_props, &ab, root, full_path, pool));
 
   /* Send successful command response with revision and props. */

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/atomic-ra-revprop-change.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/atomic-ra-revprop-change.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/atomic-ra-revprop-change.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/atomic-ra-revprop-change.c Mon Mar 16 10:10:20 2015
@@ -58,13 +58,14 @@ construct_auth_baton(svn_auth_baton_t **
                      const char *config_dir,
                      apr_pool_t *pool)
 {
-  SVN_ERR(svn_cmdline_create_auth_baton(auth_baton_p,
-                                        TRUE  /* non_interactive */,
-                                        "jrandom", "rayjandom",
-                                        config_dir,
-                                        TRUE  /* no_auth_cache */,
-                                        FALSE /* trust_server_cert */,
-                                        NULL, NULL, NULL, pool));
+  SVN_ERR(svn_cmdline_create_auth_baton2(auth_baton_p,
+                                         TRUE  /* non_interactive */,
+                                         "jrandom", "rayjandom",
+                                         config_dir,
+                                         TRUE  /* no_auth_cache */,
+                                         FALSE /* trust_server_cert */,
+                                         FALSE, FALSE, FALSE, FALSE,
+                                         NULL, NULL, NULL, pool));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/authz_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/authz_tests.py Mon Mar 16 10:10:20 2015
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-#  authz_tests.py:  testing authentication.
+#  authz_tests.py:  testing authorization.
 #
 #  Subversion is a tool for revision control.
 #  See http://subversion.apache.org for more information.

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/basic_tests.py Mon Mar 16 10:10:20 2015
@@ -3073,6 +3073,47 @@ def mkdir_parents_target_exists_on_disk(
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
 
+@Skip(svntest.main.is_ra_type_file)
+def plaintext_password_storage_disabled(sbox):
+  "test store-plaintext-passwords = no"
+
+  sbox.build()
+
+  wc_dir = sbox.wc_dir
+  sbox.simple_append("iota", "New content for iota.")
+
+  config_dir_path = sbox.get_tempname(prefix="config-dir")
+  os.mkdir(config_dir_path)
+
+  # disable all encryped password stores
+  config_file = file(os.path.join(config_dir_path, "config"), "w")
+  config_file.write("[auth]\npassword-stores =\n")
+  config_file.close()
+
+  # disable plaintext password storage
+  servers_file = file(os.path.join(config_dir_path, "servers"), "w")
+  servers_file.write("[global]\nstore-plaintext-passwords=no\n")
+  servers_file.close()
+  
+  svntest.main.run_command(svntest.main.svn_binary, False, False,
+   "commit", "--config-dir", config_dir_path,
+    "-m", "committing with plaintext password storage disabled",
+    "--username", svntest.main.wc_author,
+    "--password", svntest.main.wc_passwd,
+    "--non-interactive", wc_dir)
+
+  # Verify that the password was not stored in plaintext
+  for root, dirs, files, in os.walk(os.path.join(config_dir_path, "auth")):
+    for file_name in files:
+      path = os.path.join(root, file_name)
+      f = file(path, "r")
+      for line in f.readlines():
+        if svntest.main.wc_passwd in line:
+          f.close()
+          raise svntest.Failure("password was found in '%s'" % path)
+      f.close()
+
+
 ########################################################################
 # Run the tests
 
@@ -3142,6 +3183,7 @@ test_list = [ None,
               delete_conflicts_one_of_many,
               peg_rev_on_non_existent_wc_path,
               mkdir_parents_target_exists_on_disk,
+              plaintext_password_storage_disabled,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/davautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/davautocheck.sh?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/davautocheck.sh (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/davautocheck.sh Mon Mar 16 10:10:20 2015
@@ -596,12 +596,7 @@ if [ $# -eq 1 ] && [ "x$1" = 'x--gdb' ];
   exit
 fi
 
-
-if type time > /dev/null; then
-  TIME_CMD=time
-else
-  TIME_CMD=""
-fi
+if type time > /dev/null ; then TIME_CMD() { time "$@"; } ; else TIME_CMD() { "$@"; } ; fi
 
 MAKE=${MAKE:-make}
 
@@ -620,13 +615,13 @@ else
 fi
 
 if [ $# = 0 ]; then
-  $TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL" $SSL_MAKE_VAR
+  TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL" $SSL_MAKE_VAR
   r=$?
 else
   (cd "$ABS_BUILDDIR/subversion/tests/cmdline/"
   TEST="$1"
   shift
-  $TIME_CMD "$ABS_SRCDIR/subversion/tests/cmdline/${TEST}_tests.py" "--url=$BASE_URL" $SSL_TEST_ARG "$@")
+  TIME_CMD "$ABS_SRCDIR/subversion/tests/cmdline/${TEST}_tests.py" "--url=$BASE_URL" $SSL_TEST_ARG "$@")
   r=$?
 fi
 

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py Mon Mar 16 10:10:20 2015
@@ -3849,8 +3849,8 @@ def copy_pin_externals_wc_mixed_revision
                                      '--pin-externals')
 
 @Issue(4558)
-def copy_pin_externals_whitepace_dir(sbox):
-  "copy --pin-externals with whitepace dir"
+def copy_pin_externals_whitespace_dir(sbox):
+  "copy --pin-externals with whitespace dir"
 
   sbox.build(empty=True)
   repo_url = sbox.repo_url
@@ -4226,7 +4226,7 @@ test_list = [ None,
               copy_pin_externals_wc_local_mods,
               copy_pin_externals_wc_switched_subtrees,
               copy_pin_externals_wc_mixed_revisions,
-              copy_pin_externals_whitepace_dir,
+              copy_pin_externals_whitespace_dir,
               nested_notification,
               file_external_to_normal_file,
              ]

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/merge_tree_conflict_tests.py Mon Mar 16 10:10:20 2015
@@ -2087,6 +2087,116 @@ def merge_conflict_details(sbox):
   svntest.actions.run_and_verify_info(expected_info, sbox.ospath('B'),
                                       '--depth', 'infinity')
 
+def merge_obstruction_recording(sbox):
+  "merge obstruction recording"
+
+  sbox.build(empty=True)
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_mkdir('trunk')
+  sbox.simple_mkdir('branches')
+  sbox.simple_commit() #r1
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', sbox.repo_url + '/trunk',
+                                     sbox.repo_url + '/branches/branch',
+                                     '-mCopy') # r2
+
+  sbox.simple_mkdir('trunk/dir')
+  sbox.simple_add_text('The file on trunk\n', 'trunk/dir/file.txt')
+  sbox.simple_commit() #r3
+
+  sbox.simple_update()
+
+  sbox.simple_mkdir('branches/branch/dir')
+  sbox.simple_add_text('The file on branch\n', 'branches/branch/dir/file.txt')
+  sbox.simple_commit() #r4
+
+  sbox.simple_update()
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                      'switch', '^/branches/branch', wc_dir,
+                                      '--ignore-ancestry')
+
+  expected_output = wc.State(wc_dir, {
+    'dir'          : Item(status='  ', treeconflict='C'),
+    'dir/file.txt' : Item(status='  ', treeconflict='A'),
+  })
+  expected_mergeinfo_output = wc.State(wc_dir, {
+    ''             : Item(status=' U'),
+    'dir'          : Item(status=' U'), # Because dir already exists
+  })
+  expected_elision_output = wc.State(wc_dir, {
+  })
+  expected_disk = wc.State('', {
+    'dir/file.txt' : Item(contents="The file on branch\n"),
+    'dir'          : Item(props={'svn:mergeinfo':''}),
+    '.'            : Item(props={'svn:mergeinfo':'/trunk:2-4'}),
+  })
+  expected_status = wc.State(wc_dir, {
+    ''             : Item(status=' M', wc_rev='4'),
+    'dir'          : Item(status=' M', treeconflict='C', wc_rev='4'),
+    'dir/file.txt' : Item(status='  ', wc_rev='4'),
+  })
+  expected_skip = wc.State('', {
+  })
+  svntest.actions.run_and_verify_merge(wc_dir, '1', '4', sbox.repo_url + '/trunk',
+                                       None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       check_props=True)
+  expected_info = [
+     {
+      "Path" : re.escape(sbox.ospath('dir')),
+      "Tree conflict": re.escape(
+          'local dir obstruction, incoming dir add upon merge' +
+          ' Source  left: (none) ^/trunk/dir@1' +
+          ' Source right: (dir) ^/trunk/dir@4')
+    },
+  ]
+
+  svntest.actions.run_and_verify_info(expected_info, sbox.ospath('dir'))
+
+  # How should the user handle this conflict?
+  # ### Would be nice if we could just accept mine (leave as is, fix mergeinfo)
+  # ### or accept theirs (delete what is here and insert copy
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'resolve', '--accept=working',
+                                     sbox.ospath('dir'))
+
+  # Redo the skipped merge as record only merge
+  expected_output = [
+    '--- Recording mergeinfo for merge of r4 into \'%s\':\n' % \
+            sbox.ospath('dir'),
+    ' G   %s\n' % sbox.ospath('dir'),
+  ]
+  # ### Why are r1-r3 not recorded?
+  # ### Guess: Because dir's history only exists since r4.
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'merge', '--record-only',
+                                     sbox.repo_url + '/trunk/dir',
+                                     sbox.ospath('dir'),
+                                     '-c', '1-4')
+
+  expected_disk = wc.State('', {
+    'dir'          : Item(props={'svn:mergeinfo':'/trunk/dir:4'}),
+    'dir/file.txt' : Item(contents="The file on branch\n"),
+    '.'            : Item(props={'svn:mergeinfo':'/trunk:2-4'}),
+  })
+  svntest.actions.verify_disk(wc_dir, expected_disk, check_props=True)
+
+  # Because r1-r3 are not recorded, the mergeinfo is not elided :(
+
+  # Even something like a two url merge wouldn't work, because dir
+  # didn't exist below trunk in r1 either.
+
+  # A resolver action could be smarter though...
+
+
 ########################################################################
 # Run the tests
 
@@ -2118,6 +2228,7 @@ test_list = [ None,
               merge_replace_causes_tree_conflict2,
               merge_replace_on_del_fails,
               merge_conflict_details,
+              merge_obstruction_recording,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py Mon Mar 16 10:10:20 2015
@@ -1694,6 +1694,75 @@ def move_conflict_details(sbox):
   svntest.actions.run_and_verify_info(expected_info, sbox.ospath('B'),
                                       '--depth', 'infinity')
 
+def move_conflict_markers(sbox):
+  "move conflict markers"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  sbox.simple_propset('key','val', 'iota', 'A/B/E', 'A/B/E/beta')
+  sbox.simple_commit()
+  sbox.simple_update('', 1)
+  sbox.simple_propset('key','false', 'iota', 'A/B/E', 'A/B/E/beta')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E'       : Item(status=' C'),
+    'A/B/E/beta'  : Item(status=' C'),
+    'iota'        : Item(status=' C'),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.tweak('iota', 'A/B/E', 'A/B/E/beta', status=' C')
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+    'A/B/E/dir_conflicts.prej' : Item(contents=
+                                      "Trying to add new property 'key'\n"
+                                      "but the property already exists.\n"
+                                      "<<<<<<< (local property value)\n"
+                                      "false||||||| (incoming 'changed from' value)\n"
+                                      "=======\n"
+                                      "val>>>>>>> (incoming 'changed to' value)\n"),
+    'A/B/E/beta.prej'          : Item(contents=
+                                      "Trying to add new property 'key'\n"
+                                      "but the property already exists.\n"
+                                      "<<<<<<< (local property value)\n"
+                                      "false||||||| (incoming 'changed from' value)\n"
+                                      "=======\n"
+                                      "val>>>>>>> (incoming 'changed to' value)\n"),
+    'iota.prej'                : Item(contents=
+                                      "Trying to add new property 'key'\n"
+                                      "but the property already exists.\n"
+                                      "<<<<<<< (local property value)\n"
+                                      "false||||||| (incoming 'changed from' value)\n"
+                                      "=======\n"
+                                      "val>>>>>>> (incoming 'changed to' value)\n"),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status)
+
+  sbox.simple_move('iota', 'A/iotb')
+  sbox.simple_move('A/B/E', 'E')
+
+  expected_status.tweak('iota', status='D ', moved_to='A/iotb')
+  expected_status.tweak('A/B/E', status='D ', moved_to='E')
+  expected_status.tweak('A/B/E/alpha', 'A/B/E/beta', status='D ')
+  expected_status.add({
+    'A/iotb'  : Item(status='A ', copied='+', moved_from='iota', wc_rev='-'),
+    'E'       : Item(status='A ', copied='+', moved_from='A/B/E', wc_rev='-'),
+    'E/beta'  : Item(status=' M', copied='+', wc_rev='-'),
+    'E/alpha' : Item(status='  ', copied='+', wc_rev='-'),
+  })
+  expected_disk.remove('iota', 'iota.prej',
+                       'A/B/E', 'A/B/E/alpha', 'A/B/E/beta',
+                       'A/B/E/dir_conflicts.prej', 
+                       'A/B/E/beta.prej')
+  expected_disk.add({
+    'A/iotb'  : Item(contents="This is the file 'iota'.\n"),
+    'E/beta'  : Item(contents="This is the file 'beta'.\n"),
+    'E/alpha' : Item(contents="This is the file 'alpha'.\n"),
+  })
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  svntest.actions.verify_disk(wc_dir, expected_disk)
 
 #######################################################################
 # Run the tests
@@ -1714,6 +1783,7 @@ test_list = [ None,
               move_to_from_external,
               revert_del_root_of_move,
               move_conflict_details,
+              move_conflict_markers,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/patch_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/patch_tests.py Mon Mar 16 10:10:20 2015
@@ -5437,6 +5437,189 @@ def patch_closest(sbox):
                                        expected_output, expected_disk,
                                        expected_status, expected_skip)
 
+@SkipUnless(svntest.main.is_posix_os)
+def patch_symlink_traversal(sbox):
+  """symlink traversal behaviour"""
+
+  sbox.build(read_only=True)
+  wc_dir = sbox.wc_dir
+  alpha_contents = "This is the file 'alpha'.\n"
+
+  # A/B/E/unversioned -> alpha
+  # A/B/E/versioned -> alpha
+  # A/B/unversioned -> E         (so A/B/unversioned/alpha is A/B/E/alpha)
+  # A/B/versioned -> E           (so A/B/versioned/alpha is A/B/E/alpha)
+  os.symlink('alpha', sbox.ospath('A/B/E/unversioned'))
+  os.symlink('alpha', sbox.ospath('A/B/E/versioned'))
+  os.symlink('E', sbox.ospath('A/B/unversioned'))
+  os.symlink('E', sbox.ospath('A/B/versioned'))
+  sbox.simple_add('A/B/E/versioned', 'A/B/versioned')
+
+  prepatch_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  prepatch_status.add({'A/B/E/versioned' : Item(status='A ', wc_rev='-')})
+  prepatch_status.add({'A/B/versioned' : Item(status='A ', wc_rev='-')})
+  svntest.actions.run_and_verify_status(wc_dir, prepatch_status)
+
+  # Patch through unversioned symlink to file
+  unidiff_patch = (
+    "Index: A/B/E/unversioned\n"
+    "===================================================================\n"
+    "--- A/B/E/unversioned\t(revision 2)\n"
+    "+++ A/B/E/unversioned\t(working copy)\n"
+    "@@ -1 +1,2 @@\n"
+    " This is the file 'alpha'.\n"
+    "+xx\n"
+    )
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, unidiff_patch)
+
+  expected_output = [
+    'Skipped missing target: \'%s\'\n' % sbox.ospath('A/B/E/unversioned'),
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({'A/B/E/unversioned' : Item(contents=alpha_contents)})
+  expected_disk.add({'A/B/E/versioned' : Item(contents=alpha_contents)})
+  expected_disk.add({'A/B/unversioned' : Item()})
+  expected_disk.add({'A/B/versioned' : Item()})
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.add({'A/B/E/versioned' : Item(status='A ', wc_rev='-')})
+  expected_status.add({'A/B/versioned' : Item(status='A ', wc_rev='-')})
+  expected_skip = wc.State('', {
+    sbox.ospath('A/B/E/unversioned') : Item(verb='Skipped missing target'),
+  })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+  svntest.actions.run_and_verify_status(wc_dir, prepatch_status)
+
+  # Patch through versioned symlink to file
+  unidiff_patch = (
+    "Index: A/B/E/versioned\n"
+    "===================================================================\n"
+    "--- A/B/E/versioned\t(revision 2)\n"
+    "+++ A/B/E/versioned\t(working copy)\n"
+    "@@ -1 +1,2 @@\n"
+    " This is the file 'alpha'.\n"
+    "+xx\n"
+    )
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, unidiff_patch)
+  reject_contents = (
+    "--- A/B/E/versioned\n"
+    "+++ A/B/E/versioned\n"
+    "@@ -1,1 +1,2 @@\n"
+    " This is the file 'alpha'.\n"
+    "+xx\n"
+  )
+
+  expected_output = [
+    'C         %s\n' % sbox.ospath('A/B/E/versioned'),
+    '>         rejected hunk @@ -1,1 +1,2 @@\n',
+  ] + svntest.main.summary_of_conflicts(text_conflicts=1)
+  expected_disk.add({'A/B/E/versioned.svnpatch.rej'
+                     : Item(contents=reject_contents)})
+  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)
+  os.remove(sbox.ospath('A/B/E/versioned.svnpatch.rej'))
+  expected_disk.remove('A/B/E/versioned.svnpatch.rej')
+  svntest.actions.run_and_verify_status(wc_dir, prepatch_status)
+
+  # Patch through unversioned symlink to parent of file
+  unidiff_patch = (
+    "Index: A/B/unversioned/alpha\n"
+    "===================================================================\n"
+    "--- A/B/unversioned/alpha\t(revision 2)\n"
+    "+++ A/B/unversioned/alpha\t(working copy)\n"
+    "@@ -1 +1,2 @@\n"
+    " This is the file 'alpha'.\n"
+    "+xx\n"
+    )
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, unidiff_patch)
+
+  expected_output = [
+    'Skipped missing target: \'%s\'\n' % sbox.ospath('A/B/unversioned/alpha'),
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+  expected_skip = wc.State('', {
+    sbox.ospath('A/B/unversioned/alpha') : Item(verb='Skipped missing target'),
+  })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+  svntest.actions.run_and_verify_status(wc_dir, prepatch_status)
+
+  # Patch through versioned symlink to parent of file
+  unidiff_patch = (
+    "Index: A/B/versioned/alpha\n"
+    "===================================================================\n"
+    "--- A/B/versioned/alpha\t(revision 2)\n"
+    "+++ A/B/versioned/alpha\t(working copy)\n"
+    "@@ -1 +1,2 @@\n"
+    " This is the file 'alpha'.\n"
+    "+xx\n"
+    )
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, unidiff_patch)
+
+  expected_output = [
+    'Skipped missing target: \'%s\'\n' % sbox.ospath('A/B/versioned/alpha'),
+  ] + svntest.main.summary_of_conflicts(skipped_paths=1)
+  expected_skip = wc.State('', {
+    sbox.ospath('A/B/versioned/alpha') :  Item(verb='Skipped missing target'),
+  })
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output, expected_disk,
+                                       expected_status, expected_skip)
+  svntest.actions.run_and_verify_status(wc_dir, prepatch_status)
+
+@SkipUnless(svntest.main.is_posix_os)
+def patch_obstructing_symlink_traversal(sbox):
+  """obstructing symlink traversal behaviour"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  alpha_contents = "This is the file 'alpha'.\n"
+  sbox.simple_append('A/B/F/alpha', alpha_contents)
+  sbox.simple_add('A/B/F/alpha')
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Unversioned symlink A/B/E -> F obstructing versioned A/B/E so
+  # versioned A/B/E/alpha is A/B/F/alpha
+  svntest.main.safe_rmtree(sbox.ospath('A/B/E'))
+  os.symlink('F', sbox.ospath('A/B/E'))
+
+  unidiff_patch = (
+    "Index: A/B/E/alpha\n"
+    "===================================================================\n"
+    "--- A/B/E/alpha\t(revision 2)\n"
+    "+++ A/B/E/alpha\t(working copy)\n"
+    "@@ -1 +1,2 @@\n"
+    " This is the file 'alpha'.\n"
+    "+xx\n"
+    )
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, unidiff_patch)
+
+  ### Patch applies through the unversioned symlink
+  expected_output = [
+    'U         %s\n' % sbox.ospath('A/B/E/alpha'),
+  ]
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta')
+  expected_disk.add({'A/B/F/alpha' : Item(contents=alpha_contents+"xx\n")})
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({'A/B/F/alpha' : Item(status='  ', wc_rev=2)})
+  expected_status.tweak('A/B/E', status='~ ')
+  expected_status.tweak('A/B/E/alpha', 'A/B/F/alpha', status='M ')
+  expected_status.tweak('A/B/E/beta', status='! ')
+  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)
+
 ########################################################################
 #Run the tests
 
@@ -5496,6 +5679,8 @@ test_list = [ None,
               patch_hunk_overlap,
               patch_delete_modified,
               patch_closest,
+              patch_symlink_traversal,
+              patch_obstructing_symlink_traversal,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py Mon Mar 16 10:10:20 2015
@@ -2783,6 +2783,31 @@ def wc_propop_on_url(sbox):
                                      'pg', 'my:Q', '-r', 'PREV',
                                      sbox.repo_url)
 
+def prop_conflict_root(sbox):
+  """property conflict on wc root"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_propset('propname', 'propval1', '')
+  sbox.simple_commit()
+  sbox.simple_propset('propname', 'propval2', '')
+  sbox.simple_commit()
+  sbox.simple_update(revision=2)
+  sbox.simple_propset('propname', 'propvalconflict', '')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    '' : Item(status=' C'),
+  })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+  expected_status.tweak('', status=' C')
+  extra_files = ['dir_conflicts.prej']
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        extra_files=extra_files)
 
 ########################################################################
 # Run the tests
@@ -2834,6 +2859,7 @@ test_list = [ None,
               dir_prop_conflict_details,
               iprops_list_abspath,
               wc_propop_on_url,
+              prop_conflict_root,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnserveautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnserveautocheck.sh?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnserveautocheck.sh (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnserveautocheck.sh Mon Mar 16 10:10:20 2015
@@ -92,11 +92,7 @@ random_port() {
   fi
 }
 
-if type time > /dev/null; then
-  TIME_CMD=time
-else
-  TIME_CMD=""
-fi
+if type time > /dev/null ; then TIME_CMD() { time "$@"; } ; else TIME_CMD() { "$@"; } ; fi
 
 MAKE=${MAKE:-make}
 
@@ -121,13 +117,13 @@ fi
 
 BASE_URL=svn://127.0.0.1:$SVNSERVE_PORT
 if [ $# = 0 ]; then
-  $TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL"
+  TIME_CMD "$MAKE" check "BASE_URL=$BASE_URL"
   r=$?
 else
   cd "$ABS_BUILDDIR/subversion/tests/cmdline/"
   TEST="$1"
   shift
-  $TIME_CMD "./${TEST}_tests.py" "--url=$BASE_URL" $*
+  TIME_CMD "./${TEST}_tests.py" "--url=$BASE_URL" $*
   r=$?
   cd - > /dev/null
 fi

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py Mon Mar 16 10:10:20 2015
@@ -1534,9 +1534,16 @@ def is_plaintext_password_storage_disabl
 
 
 # https://issues.apache.org/bugzilla/show_bug.cgi?id=56480
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=55397
 __mod_dav_url_quoting_broken_versions = frozenset([
+    '2.2.27',
     '2.2.26',
+    '2.2.25',
     '2.4.9',
+    '2.4.8',
+    '2.4.7',
+    '2.4.6',
+    '2.4.5',
 ])
 def is_mod_dav_url_quoting_broken():
     if is_ra_type_dav():

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py Mon Mar 16 10:10:20 2015
@@ -1448,9 +1448,14 @@ def auto_analyze(sbox):
                             '52ec7e4b-e5f0-451d-829f-f05d5571b4ab')
 
   # Don't use svn to do relocate as that will add the table.
-  val = svntest.wc.sqlite_exec(sbox.wc_dir,
-                               "update repository "
-                               "set root ='" + sbox.repo_url + "'");
+  svntest.wc.sqlite_exec(sbox.wc_dir,
+                         "update repository "
+                         "set root ='" + sbox.repo_url + "'")
+  val = svntest.wc.sqlite_stmt(sbox.wc_dir,
+                               "select 1 from sqlite_master "
+                               "where name = 'sqlite_stat1'")
+  if val != []:
+    raise svntest.Failure("initial state failed")
 
   # Make working copy read-only (but not wc_dir itself as
   # svntest.main.chmod_tree will not reset it.)

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests_data/wc-without-stat1.tar.bz2
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests_data/wc-without-stat1.tar.bz2?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
Binary files - no diff available.

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c?rev=1666947&r1=1666946&r2=1666947&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c Mon Mar 16 10:10:20 2015
@@ -4339,6 +4339,195 @@ check_related(const svn_test_opts_t *opt
 
 
 static svn_error_t *
+check_txn_related(const svn_test_opts_t *opts,
+                  apr_pool_t *pool)
+{
+  apr_pool_t *subpool = svn_pool_create(pool);
+  svn_fs_t *fs;
+  svn_fs_txn_t *txn[3];
+  svn_fs_root_t *root[3];
+  svn_revnum_t youngest_rev = 0;
+
+  /* Create a filesystem and repository. */
+  SVN_ERR(svn_test__create_fs(&fs, "test-repo-check-related",
+                              opts, pool));
+
+  /*** Step I: Build up some state in our repository through a series
+       of commits */
+
+  /* This is the node graph we are testing.  It contains one revision (r1)
+     and two transactions, T1 and T2 - yet uncommitted.
+
+     A is a file that exists in r1 (A-0) and gets modified in both txns.
+     C is a copy of A1 made in both txns.
+     B is a new node created in both txns
+     D is a file that exists in r1 (D-0) and never gets modified.
+
+                 +--A-0--+                  D-0
+                 |       |
+           +-----+       +-----+
+           |     |       |     |
+     B-1   C-T   A-1     A-2   C-1   B-2
+  */
+  /* Revision 1 */
+  SVN_ERR(svn_fs_begin_txn(&txn[0], fs, youngest_rev, subpool));
+  SVN_ERR(svn_fs_txn_root(&root[0], txn[0], subpool));
+  SVN_ERR(svn_fs_make_file(root[0], "A", subpool));
+  SVN_ERR(svn_test__set_file_contents(root[0], "A", "1", subpool));
+  SVN_ERR(svn_fs_make_file(root[0], "D", subpool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn[0], subpool));
+  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+  svn_pool_clear(subpool);
+  SVN_ERR(svn_fs_revision_root(&root[0], fs, youngest_rev, pool));
+
+  /* Transaction 1 */
+  SVN_ERR(svn_fs_begin_txn(&txn[1], fs, youngest_rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root[1], txn[1], pool));
+  SVN_ERR(svn_test__set_file_contents(root[1], "A", "2", pool));
+  SVN_ERR(svn_fs_copy(root[0], "A", root[1], "C", pool));
+  SVN_ERR(svn_fs_make_file(root[1], "B", pool));
+
+  /* Transaction 2 */
+  SVN_ERR(svn_fs_begin_txn(&txn[2], fs, youngest_rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root[2], txn[2], pool));
+  SVN_ERR(svn_test__set_file_contents(root[2], "A", "2", pool));
+  SVN_ERR(svn_fs_copy(root[0], "A", root[2], "C", pool));
+  SVN_ERR(svn_fs_make_file(root[2], "B", pool));
+
+  /*** Step II: Exhaustively verify relationship between all nodes in
+       existence. */
+  {
+    int i, j;
+
+    struct path_rev_t
+    {
+      const char *path;
+      int root;
+    };
+
+    /* Our 16 existing files/revisions. */
+    struct path_rev_t path_revs[8] = {
+      { "A", 0 }, { "A", 1 }, { "A", 2 },
+      { "B", 1 }, { "B", 2 },
+      { "C", 1 }, { "C", 2 },
+      { "D", 0 }
+    };
+
+    int related_matrix[8][8] = {
+      /* A-0 ... D-0 across the top here*/
+      { 1, 1, 1, 0, 0, 1, 1, 0 }, /* A-0 */
+      { 1, 1, 1, 0, 0, 1, 1, 0 }, /* A-1 */
+      { 1, 1, 1, 0, 0, 1, 1, 0 }, /* A-2 */
+      { 0, 0, 0, 1, 0, 0, 0, 0 }, /* C-1 */
+      { 0, 0, 0, 0, 1, 0, 0, 0 }, /* C-2 */
+      { 1, 1, 1, 0, 0, 1, 1, 0 }, /* B-1 */
+      { 1, 1, 1, 0, 0, 1, 1, 0 }, /* B-2 */
+      { 0, 0, 0, 0, 0, 0, 0, 1 }  /* D-0 */
+    };
+
+    /* Here's the fun part.  Running the tests. */
+    for (i = 0; i < 8; i++)
+      {
+        for (j = 0; j < 8; j++)
+          {
+            struct path_rev_t pr1 = path_revs[i];
+            struct path_rev_t pr2 = path_revs[j];
+            const svn_fs_id_t *id1, *id2;
+            int related = 0;
+            svn_fs_node_relation_t relation;
+
+            svn_pool_clear(subpool);
+
+            /* Get the ID for the first path/revision combination. */
+            SVN_ERR(svn_fs_node_id(&id1, root[pr1.root], pr1.path, subpool));
+
+            /* Get the ID for the second path/revision combination. */
+            SVN_ERR(svn_fs_node_id(&id2, root[pr2.root], pr2.path, subpool));
+
+            /* <exciting> Now, run the relationship check! </exciting> */
+            related = svn_fs_check_related(id1, id2) ? 1 : 0;
+            if (related == related_matrix[i][j])
+              {
+                /* xlnt! */
+              }
+            else if ((! related) && related_matrix[i][j])
+              {
+                return svn_error_createf
+                  (SVN_ERR_TEST_FAILED, NULL,
+                   "expected '%s-%d' to be related to '%s-%d'; it was not",
+                   pr1.path, pr1.root, pr2.path, pr2.root);
+              }
+            else if (related && (! related_matrix[i][j]))
+              {
+                return svn_error_createf
+                  (SVN_ERR_TEST_FAILED, NULL,
+                   "expected '%s-%d' to not be related to '%s-%d'; it was",
+                   pr1.path, pr1.root, pr2.path, pr2.root);
+              }
+
+            /* Asking directly, i.e. without involving the noderev IDs as
+             * an intermediate, should yield the same results. */
+            SVN_ERR(svn_fs_node_relation(&relation, root[pr1.root], pr1.path,
+                                         root[pr2.root], pr2.path, subpool));
+            if (i == j)
+              {
+                /* Identical note. */
+                if (!related || relation != svn_fs_node_same)
+                  {
+                    return svn_error_createf
+                      (SVN_ERR_TEST_FAILED, NULL,
+                      "expected '%s-%d' to be the same as '%s-%d';"
+                      " it was not",
+                      pr1.path, pr1.root, pr2.path, pr2.root);
+                  }
+              }
+            else if (related && relation != svn_fs_node_common_ancestor)
+              {
+                return svn_error_createf
+                  (SVN_ERR_TEST_FAILED, NULL,
+                   "expected '%s-%d' to have a common ancestor with '%s-%d';"
+                   " it had not",
+                   pr1.path, pr1.root, pr2.path, pr2.root);
+              }
+            else if (!related && relation != svn_fs_node_unrelated)
+              {
+                return svn_error_createf
+                  (SVN_ERR_TEST_FAILED, NULL,
+                   "expected '%s-%d' to not be related to '%s-%d'; it was",
+                   pr1.path, pr1.root, pr2.path, pr2.root);
+              }
+          } /* for ... */
+      } /* for ... */
+
+    /* Verify that the noderevs stay the same after their last change.
+       There is only D that is not changed. */
+    for (i = 1; i <= 2; ++i)
+      {
+        svn_fs_node_relation_t relation;
+        svn_pool_clear(subpool);
+
+        /* Query their noderev relationship to the latest change. */
+        SVN_ERR(svn_fs_node_relation(&relation, root[i], "D",
+                                     root[0], "D", subpool));
+
+        /* They shall use the same noderevs */
+        if (relation != svn_fs_node_same)
+          {
+            return svn_error_createf
+              (SVN_ERR_TEST_FAILED, NULL,
+              "expected 'D-%d' to be the same as 'D-0'; it was not", i);
+          }
+      } /* for ... */
+  }
+
+  /* Destroy the subpool. */
+  svn_pool_destroy(subpool);
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
 branch_test(const svn_test_opts_t *opts,
             apr_pool_t *pool)
 {
@@ -6915,6 +7104,8 @@ static struct svn_test_descriptor_t test
                        "test property and text rep-sharing collision"),
     SVN_TEST_OPTS_PASS(test_internal_txn_props,
                        "test setting and getting internal txn props"),
+    SVN_TEST_OPTS_PASS(check_txn_related,
+                       "test svn_fs_check_related for transactions"),
     SVN_TEST_NULL
   };