You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pr...@apache.org on 2013/03/18 10:35:29 UTC

svn commit: r1457684 [7/22] - in /subversion/branches/verify-keep-going: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ notes/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subve...

Modified: subversion/branches/verify-keep-going/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_fs_fs/tree.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_fs_fs/tree.c Mon Mar 18 09:35:24 2013
@@ -857,24 +857,21 @@ typedef enum open_path_flags_t {
      has no functional impact.  */
   open_path_uncached = 2,
 
-  /* Assume that the path parameter is already in canonical form. */
-  open_path_is_canonical = 4,
-
   /* The caller does not care about the parent node chain but only
      the final DAG node. */
-  open_path_node_only = 8
+  open_path_node_only = 4
 } open_path_flags_t;
 
 
 /* Open the node identified by PATH in ROOT, allocating in POOL.  Set
    *PARENT_PATH_P to a path from the node up to ROOT.  The resulting
    **PARENT_PATH_P value is guaranteed to contain at least one
-   *element, for the root directory.
+   *element, for the root directory.  PATH must be in canonical form.
 
    If resulting *PARENT_PATH_P will eventually be made mutable and
    modified, or if copy ID inheritance information is otherwise
    needed, TXN_ID should be the ID of the mutability transaction.  If
-   TXN_ID is NULL, no copy ID in heritance information will be
+   TXN_ID is NULL, no copy ID inheritance information will be
    calculated for the *PARENT_PATH_P chain.
 
    If FLAGS & open_path_last_optional is zero, return the error
@@ -887,7 +884,8 @@ typedef enum open_path_flags_t {
 
    The remaining bits in FLAGS are hints that allow this function
    to take shortcuts based on knowledge that the caller provides,
-   such as the fact that PATH is already in canonical form.
+   such as the caller is not actually being interested in PARENT_PATH_P,
+   but only in (*PARENT_PATH_P)->NODE.
 
    NOTE: Public interfaces which only *read* from the filesystem
    should not call this function directly, but should instead use
@@ -907,21 +905,18 @@ open_path(parent_path_t **parent_path_p,
   const char *rest; /* The portion of PATH we haven't traversed yet.  */
 
   /* ensure a canonical path representation */
-  const char *canon_path = (   (flags & open_path_is_canonical)
-                            || svn_fs__is_canonical_abspath(path))
-                         ? path
-                         : svn_fs__canonicalize_abspath(path, pool);
   const char *path_so_far = "/";
   apr_pool_t *iterpool = svn_pool_create(pool);
 
   /* callers often traverse the tree in some path-based order.  That means
-     a sibbling of PATH has been resently accessed.  Try to start the lookup
+     a sibling of PATH has been presently accessed.  Try to start the lookup
      directly at the parent node, if the caller did not requested the full
      parent chain. */
   const char *directory;
+  assert(svn_fs__is_canonical_abspath(path));
   if (flags & open_path_node_only)
     {
-      directory = svn_dirent_dirname(canon_path, pool);
+      directory = svn_dirent_dirname(path, pool);
       if (directory[1] != 0) /* root nodes are covered anyway */
         SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool));
     }
@@ -930,14 +925,14 @@ open_path(parent_path_t **parent_path_p,
   if (here)
     {
       path_so_far = directory;
-      rest = canon_path + strlen(directory) + 1;
+      rest = path + strlen(directory) + 1;
     }
   else
     {
       /* Make a parent_path item for the root node, using its own current
          copy id.  */
       SVN_ERR(root_node(&here, root, pool));
-      rest = canon_path + 1; /* skip the leading '/', it saves in iteration */
+      rest = path + 1; /* skip the leading '/', it saves in iteration */
     }
  
   parent_path = make_parent_path(here, 0, 0, pool);
@@ -1182,7 +1177,7 @@ get_dag(dag_node_t **dag_node_p,
   if (! node)
     {
       /* Canonicalize the input PATH. */
-      if (!svn_fs__is_canonical_abspath(path))
+      if (! svn_fs__is_canonical_abspath(path))
         {
           path = svn_fs__canonicalize_abspath(path, pool);
 
@@ -1196,8 +1191,8 @@ get_dag(dag_node_t **dag_node_p,
           /* Call open_path with no flags, as we want this to return an
            * error if the node for which we are searching doesn't exist. */
           SVN_ERR(open_path(&parent_path, root, path,
-                            open_path_uncached | open_path_is_canonical
-                            | open_path_node_only, NULL, pool));
+                            open_path_uncached | open_path_node_only,
+                            NULL, pool));
           node = parent_path->node;
 
           /* No need to cache our find -- open_path() will do that for us. */
@@ -1424,6 +1419,7 @@ fs_change_node_prop(svn_fs_root_t *root,
     return SVN_FS__NOT_TXN(root);
   txn_id = root->txn;
 
+  path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, 0, txn_id, pool));
 
   /* Check (non-recursively) to see if path is locked; if so, check
@@ -2195,6 +2191,7 @@ fs_make_dir(svn_fs_root_t *root,
   dag_node_t *sub_dir;
   const char *txn_id = root->txn;
 
+  path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional,
                     txn_id, pool));
 
@@ -2246,6 +2243,7 @@ fs_delete_node(svn_fs_root_t *root,
   if (! root->is_txn_root)
     return SVN_FS__NOT_TXN(root);
 
+  path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, 0, txn_id, pool));
   kind = svn_fs_fs__dag_node_kind(parent_path->node);
 
@@ -2445,7 +2443,12 @@ fs_copy(svn_fs_root_t *from_root,
         const char *to_path,
         apr_pool_t *pool)
 {
-  return svn_error_trace(copy_helper(from_root, from_path, to_root, to_path,
+  return svn_error_trace(copy_helper(from_root,
+                                     svn_fs__canonicalize_abspath(from_path,
+                                                                  pool),
+                                     to_root,
+                                     svn_fs__canonicalize_abspath(to_path,
+                                                                  pool),
                                      TRUE, pool));
 }
 
@@ -2462,6 +2465,7 @@ fs_revision_link(svn_fs_root_t *from_roo
   if (! to_root->is_txn_root)
     return SVN_FS__NOT_TXN(to_root);
 
+  path = svn_fs__canonicalize_abspath(path, pool);
   return svn_error_trace(copy_helper(from_root, path, to_root, path,
                                      FALSE, pool));
 }
@@ -2537,8 +2541,9 @@ fs_make_file(svn_fs_root_t *root,
   dag_node_t *child;
   const char *txn_id = root->txn;
 
+  path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional,
-                    txn_id, pool));
+                   txn_id, pool));
 
   /* If there's already a file by that name, complain.
      This also catches the case of trying to make a file named `/'.  */
@@ -2846,7 +2851,7 @@ fs_apply_textdelta(svn_txdelta_window_ha
   txdelta_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
 
   tb->root = root;
-  tb->path = path;
+  tb->path = svn_fs__canonicalize_abspath(path, pool);
   tb->pool = pool;
   tb->base_checksum = svn_checksum_dup(base_checksum, pool);
   tb->result_checksum = svn_checksum_dup(result_checksum, pool);
@@ -2979,7 +2984,7 @@ fs_apply_text(svn_stream_t **contents_p,
   struct text_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
 
   tb->root = root;
-  tb->path = path;
+  tb->path = svn_fs__canonicalize_abspath(path, pool);
   tb->pool = pool;
   tb->result_checksum = svn_checksum_dup(result_checksum, pool);
 
@@ -3199,6 +3204,7 @@ static svn_error_t *fs_closest_copy(svn_
   *root_p = NULL;
   *path_p = NULL;
 
+  path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, 0, NULL, pool));
 
   /* Find the youngest copyroot in the path of this node-rev, which
@@ -3677,7 +3683,7 @@ assemble_history(svn_fs_t *fs,
 {
   svn_fs_history_t *history = apr_pcalloc(pool, sizeof(*history));
   fs_history_data_t *fhd = apr_pcalloc(pool, sizeof(*fhd));
-  fhd->path = path;
+  fhd->path = svn_fs__canonicalize_abspath(path, pool);
   fhd->revision = revision;
   fhd->is_interesting = is_interesting;
   fhd->path_hint = path_hint;
@@ -3830,8 +3836,7 @@ get_mergeinfo_for_path_internal(svn_merg
 
   path = svn_fs__canonicalize_abspath(path, scratch_pool);
 
-  SVN_ERR(open_path(&parent_path, rev_root, path, open_path_is_canonical,
-                    NULL, scratch_pool));
+  SVN_ERR(open_path(&parent_path, rev_root, path, 0, NULL, scratch_pool));
 
   if (inherit == svn_mergeinfo_nearest_ancestor && ! parent_path->parent)
     return SVN_NO_ERROR;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_fs_util/fs-util.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_fs_util/fs-util.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_fs_util/fs-util.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_fs_util/fs-util.c Mon Mar 18 09:35:24 2013
@@ -35,26 +35,19 @@
 #include "private/svn_fspath.h"
 #include "../libsvn_fs/fs-loader.h"
 
-svn_boolean_t
-svn_fs__is_canonical_abspath(const char *path)
+/* Return TRUE, if PATH of PATH_LEN > 0 chars starts with a '/' and does
+ * not end with a '/' and does not contain duplicate '/'.
+ */
+static svn_boolean_t
+is_canonical_abspath(const char *path, size_t path_len)
 {
-  size_t path_len;
   const char *end;
 
-  /* No PATH?  No problem. */
-  if (! path)
-    return TRUE;
-
-  /* Empty PATH?  That's just "/". */
-  if (! *path)
-    return FALSE;
-
-  /* No leading slash?  Fix that. */
-  if (*path != '/')
+  /* check for leading '/' */
+  if (path[0] != '/')
     return FALSE;
 
   /* check for trailing '/' */
-  path_len = strlen(path);
   if (path_len == 1)
     return TRUE;
   if (path[path_len - 1] == '/')
@@ -69,6 +62,21 @@ svn_fs__is_canonical_abspath(const char 
   return TRUE;
 }
 
+svn_boolean_t
+svn_fs__is_canonical_abspath(const char *path)
+{
+  /* No PATH?  No problem. */
+  if (! path)
+    return TRUE;
+
+  /* Empty PATH?  That's just "/". */
+  if (! *path)
+    return FALSE;
+
+  /* detailed checks */
+  return is_canonical_abspath(path, strlen(path));
+}
+
 const char *
 svn_fs__canonicalize_abspath(const char *path, apr_pool_t *pool)
 {
@@ -83,12 +91,16 @@ svn_fs__canonicalize_abspath(const char 
 
   /* Empty PATH?  That's just "/". */
   if (! *path)
-    return apr_pstrdup(pool, "/");
+    return "/";
+
+  /* Non-trivial cases.  Maybe, the path already is canonical after all? */
+  path_len = strlen(path);
+  if (is_canonical_abspath(path, path_len))
+    return apr_pstrmemdup(pool, path, path_len);
 
   /* Now, the fun begins.  Alloc enough room to hold PATH with an
      added leading '/'. */
-  path_len = strlen(path);
-  newpath = apr_pcalloc(pool, path_len + 2);
+  newpath = apr_palloc(pool, path_len + 2);
 
   /* No leading slash?  Fix that. */
   if (*path != '/')
@@ -123,6 +135,8 @@ svn_fs__canonicalize_abspath(const char 
      the root directory case)? */
   if ((newpath[newpath_i - 1] == '/') && (newpath_i > 1))
     newpath[newpath_i - 1] = '\0';
+  else
+    newpath[newpath_i] = '\0';
 
   return newpath;
 }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra/deprecated.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra/deprecated.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra/deprecated.c Mon Mar 18 09:35:24 2013
@@ -373,6 +373,31 @@ svn_error_t *svn_ra_do_update(svn_ra_ses
                                     pool);
 }
 
+
+svn_error_t *
+svn_ra_do_switch2(svn_ra_session_t *session,
+                  const svn_ra_reporter3_t **reporter,
+                  void **report_baton,
+                  svn_revnum_t revision_to_switch_to,
+                  const char *switch_target,
+                  svn_depth_t depth,
+                  const char *switch_url,
+                  const svn_delta_editor_t *switch_editor,
+                  void *switch_baton,
+                  apr_pool_t *pool)
+{
+  return svn_error_trace(
+            svn_ra_do_switch3(session,
+                              reporter, report_baton,
+                              revision_to_switch_to, switch_target,
+                              depth,
+                              switch_url,
+                              FALSE /* send_copyfrom_args */,
+                              TRUE /* ignore_ancestry */,
+                              switch_editor, switch_baton,
+                              pool, pool));
+}
+
 svn_error_t *svn_ra_do_switch(svn_ra_session_t *session,
                               const svn_ra_reporter2_t **reporter,
                               void **report_baton,
@@ -393,8 +418,11 @@ svn_error_t *svn_ra_do_switch(svn_ra_ses
                                     &(b->reporter3), &(b->reporter3_baton),
                                     revision_to_switch_to, switch_target,
                                     SVN_DEPTH_INFINITY_OR_FILES(recurse),
-                                    switch_url, switch_editor, switch_baton,
-                                    pool);
+                                    switch_url,
+                                    FALSE /* send_copyfrom_args */,
+                                    TRUE /* ignore_ancestry */,
+                                    switch_editor, switch_baton,
+                                    pool, pool);
 }
 
 svn_error_t *svn_ra_do_status(svn_ra_session_t *session,

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.c Mon Mar 18 09:35:24 2013
@@ -804,24 +804,32 @@ svn_error_t *svn_ra_do_update2(svn_ra_se
                                     pool);
 }
 
-svn_error_t *svn_ra_do_switch2(svn_ra_session_t *session,
-                               const svn_ra_reporter3_t **reporter,
-                               void **report_baton,
-                               svn_revnum_t revision_to_switch_to,
-                               const char *switch_target,
-                               svn_depth_t depth,
-                               const char *switch_url,
-                               const svn_delta_editor_t *switch_editor,
-                               void *switch_baton,
-                               apr_pool_t *pool)
+svn_error_t *
+svn_ra_do_switch3(svn_ra_session_t *session,
+                  const svn_ra_reporter3_t **reporter,
+                  void **report_baton,
+                  svn_revnum_t revision_to_switch_to,
+                  const char *switch_target,
+                  svn_depth_t depth,
+                  const char *switch_url,
+                  svn_boolean_t send_copyfrom_args,
+                  svn_boolean_t ignore_ancestry,
+                  const svn_delta_editor_t *switch_editor,
+                  void *switch_baton,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   SVN_ERR_ASSERT(svn_path_is_empty(switch_target)
                  || svn_path_is_single_path_component(switch_target));
   return session->vtable->do_switch(session,
                                     reporter, report_baton,
                                     revision_to_switch_to, switch_target,
-                                    depth, switch_url, switch_editor,
-                                    switch_baton, pool);
+                                    depth, switch_url,
+                                    send_copyfrom_args,
+                                    ignore_ancestry,
+                                    switch_editor,
+                                    switch_baton,
+                                    result_pool, scratch_pool);
 }
 
 svn_error_t *svn_ra_do_status2(svn_ra_session_t *session,

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.h?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra/ra_loader.h Mon Mar 18 09:35:24 2013
@@ -154,9 +154,12 @@ typedef struct svn_ra__vtable_t {
                             const char *switch_target,
                             svn_depth_t depth,
                             const char *switch_url,
+                            svn_boolean_t send_copyfrom_args,
+                            svn_boolean_t ignore_ancestry,
                             const svn_delta_editor_t *switch_editor,
                             void *switch_baton,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
   /* See svn_ra_do_status2(). */
   svn_error_t *(*do_status)(svn_ra_session_t *session,
                             const svn_ra_reporter3_t **reporter,

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra/wrapper_template.h?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra/wrapper_template.h Mon Mar 18 09:35:24 2013
@@ -315,7 +315,11 @@ static svn_error_t *compat_do_switch(voi
 
   SVN_ERR(VTBL.do_switch(session_baton, &reporter3, &baton3,
                          revision_to_switch_to, switch_target, depth,
-                         switch_url, editor, switch_baton, pool));
+                         switch_url,
+                         FALSE /* send_copyfrom_args */,
+                         TRUE /* ignore_ancestry */,
+                         editor, switch_baton,
+                         pool /* result_pool */, pool /* scratch_pool */));
 
   compat_wrap_reporter(reporter, report_baton, reporter3, baton3, pool);
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_local/ra_plugin.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_local/ra_plugin.c Mon Mar 18 09:35:24 2013
@@ -838,9 +838,12 @@ svn_ra_local__do_switch(svn_ra_session_t
                         const char *update_target,
                         svn_depth_t depth,
                         const char *switch_url,
+                        svn_boolean_t send_copyfrom_args,
+                        svn_boolean_t ignore_ancestry,
                         const svn_delta_editor_t *update_editor,
                         void *update_baton,
-                        apr_pool_t *pool)
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
 {
   return make_reporter(session,
                        reporter,
@@ -848,13 +851,13 @@ svn_ra_local__do_switch(svn_ra_session_t
                        update_revision,
                        update_target,
                        switch_url,
-                       TRUE,
+                       TRUE /* text_deltas */,
                        depth,
-                       FALSE,   /* ### TODO(sussman): take new arg */
-                       TRUE,
+                       send_copyfrom_args,
+                       ignore_ancestry,
                        update_editor,
                        update_baton,
-                       pool);
+                       result_pool);
 }
 
 
@@ -1513,7 +1516,10 @@ svn_ra_local__has_capability(svn_ra_sess
       || strcmp(capability, SVN_RA_CAPABILITY_PARTIAL_REPLAY) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0
-      || strcmp(capability, SVN_RA_CAPABILITY_INHERITED_PROPS) == 0)
+      || strcmp(capability, SVN_RA_CAPABILITY_INHERITED_PROPS) == 0
+      || strcmp(capability, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS) == 0
+      || strcmp(capability, SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE) == 0
+      )
     {
       *has = TRUE;
     }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/commit.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/commit.c Mon Mar 18 09:35:24 2013
@@ -1385,16 +1385,26 @@ open_root(void *edit_baton,
     }
   else
     {
-      const char *activity_str;
+      const char *activity_str = ctx->session->activity_collection_url;
 
-      SVN_ERR(svn_ra_serf__v1_get_activity_collection(&activity_str,
-                                                      ctx->session->conns[0],
-                                                      ctx->pool,
-                                                      ctx->pool));
       if (!activity_str)
-        return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
-                                _("The OPTIONS response did not include the "
-                                  "requested activity-collection-set value"));
+        SVN_ERR(svn_ra_serf__v1_get_activity_collection(&activity_str,
+                                                        ctx->session->conns[0],
+                                                        ctx->pool,
+                                                        ctx->pool));
+
+      /* Cache the result. */
+      if (activity_str)
+        {
+          ctx->session->activity_collection_url =
+            apr_pstrdup(ctx->session->pool, activity_str);
+        }
+      else
+        {
+          return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
+                                  _("The OPTIONS response did not include the "
+                                    "requested activity-collection-set value"));
+        }
 
       ctx->activity_url =
         svn_path_url_add_component2(activity_str, svn_uuid_generate(ctx->pool),

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/getlocks.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/getlocks.c Mon Mar 18 09:35:24 2013
@@ -262,10 +262,17 @@ svn_ra_serf__get_locks(svn_ra_session_t 
   handler->body_delegate = create_getlocks_body;
   handler->body_delegate_baton = lock_ctx;
 
-  /* ### use svn_ra_serf__error_on_status() ?  */
-
   SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
+  /* We get a 404 when a path doesn't exist in HEAD, but it might
+     have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */
+  if (handler->sline.code != 404)
+    {
+      SVN_ERR(svn_ra_serf__error_on_status(handler->sline.code,
+                                           handler->path,
+                                           handler->location));
+    }
+
   *locks = lock_ctx->hash;
 
   return SVN_NO_ERROR;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/options.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/options.c Mon Mar 18 09:35:24 2013
@@ -203,6 +203,13 @@ capabilities_headers_iterator_callback(v
           svn_hash_sets(session->capabilities,
                         SVN_RA_CAPABILITY_INHERITED_PROPS, capability_yes);
         }
+      if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_GET_FILE_REVS_REVERSE,
+                                 vals))
+        {
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE,
+                        capability_yes);
+        }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS, vals))
         {
           svn_hash_sets(session->capabilities,
@@ -428,6 +435,9 @@ svn_ra_serf__v2_get_youngest_revnum(svn_
 
   SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
   SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
+  SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
+                                       opt_ctx->handler->path,
+                                       opt_ctx->handler->location));
 
   *youngest = opt_ctx->youngest_rev;
 
@@ -449,6 +459,10 @@ svn_ra_serf__v1_get_activity_collection(
   SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
   SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
 
+  SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
+                                       opt_ctx->handler->path,
+                                       opt_ctx->handler->location));
+
   *activity_url = apr_pstrdup(result_pool, opt_ctx->activity_collection);
 
   return SVN_NO_ERROR;
@@ -483,11 +497,22 @@ svn_ra_serf__exchange_capabilities(svn_r
       return SVN_NO_ERROR;
     }
 
-  return svn_error_compose_create(
-             svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
-                                          serf_sess->session_url.path,
-                                          opt_ctx->handler->location),
-             err);
+  SVN_ERR(svn_error_compose_create(
+              svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
+                                           serf_sess->session_url.path,
+                                           opt_ctx->handler->location),
+              err));
+
+  /* Opportunistically cache any reported activity URL.  (We don't
+     want to have to ask for this again later, potentially against an
+     unreadable commit anchor URL.)  */
+  if (opt_ctx->activity_collection)
+    {
+      serf_sess->activity_collection_url =
+        apr_pstrdup(serf_sess->pool, opt_ctx->activity_collection);
+    }
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/property.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/property.c Mon Mar 18 09:35:24 2013
@@ -638,13 +638,8 @@ svn_ra_serf__wait_for_props(svn_ra_serf_
   err2 = svn_ra_serf__error_on_status(handler->sline.code,
                                       handler->path,
                                       handler->location);
-  if (err2)
-    {
-      svn_error_clear(err);
-      return err2;
-    }
 
-  return err;
+  return svn_error_compose_create(err2, err);
 }
 
 /*
@@ -1208,7 +1203,7 @@ svn_ra_serf__get_stable_url(const char *
 
 
 svn_error_t *
-svn_ra_serf__get_resource_type(svn_kind_t *kind,
+svn_ra_serf__get_resource_type(svn_node_kind_t *kind,
                                apr_hash_t *props)
 {
   apr_hash_t *dav_props;
@@ -1226,11 +1221,11 @@ svn_ra_serf__get_resource_type(svn_kind_
 
   if (strcmp(res_type, "collection") == 0)
     {
-      *kind = svn_kind_dir;
+      *kind = svn_node_dir;
     }
   else
     {
-      *kind = svn_kind_file;
+      *kind = svn_node_file;
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/ra_serf.h?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/ra_serf.h Mon Mar 18 09:35:24 2013
@@ -180,6 +180,10 @@ struct svn_ra_serf__session_t {
      constants' addresses, therefore). */
   apr_hash_t *capabilities;
 
+  /* Activity collection URL.  (Cached from the initial OPTIONS
+     request when run against HTTPv1 servers.)  */
+  const char *activity_collection_url;
+
   /* Are we using a proxy? */
   int using_proxy;
 
@@ -1297,7 +1301,7 @@ svn_ra_serf__set_prop(apr_hash_t *props,
                       const svn_string_t *val, apr_pool_t *pool);
 
 svn_error_t *
-svn_ra_serf__get_resource_type(svn_kind_t *kind,
+svn_ra_serf__get_resource_type(svn_node_kind_t *kind,
                                apr_hash_t *props);
 
 
@@ -1537,9 +1541,12 @@ svn_ra_serf__do_switch(svn_ra_session_t 
                        const char *switch_target,
                        svn_depth_t depth,
                        const char *switch_url,
+                       svn_boolean_t send_copyfrom_args,
+                       svn_boolean_t ignore_ancestry,
                        const svn_delta_editor_t *switch_editor,
                        void *switch_baton,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool);
 
 /* Implements svn_ra__vtable_t.get_file_revs(). */
 svn_error_t *

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/serf.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/serf.c Mon Mar 18 09:35:24 2013
@@ -673,14 +673,11 @@ svn_ra_serf__check_path(svn_ra_session_t
     }
   else
     {
-      svn_kind_t res_kind;
-
       /* Any other error, raise to caller. */
       if (err)
         return svn_error_trace(err);
 
-      SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, props));
-      *kind = svn__node_kind_from_kind(res_kind);
+      SVN_ERR(svn_ra_serf__get_resource_type(kind, props));
     }
 
   return SVN_NO_ERROR;
@@ -956,11 +953,11 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
 static svn_error_t *
 resource_is_directory(apr_hash_t *props)
 {
-  svn_kind_t kind;
+  svn_node_kind_t kind;
 
   SVN_ERR(svn_ra_serf__get_resource_type(&kind, props));
 
-  if (kind != svn_kind_dir)
+  if (kind != svn_node_dir)
     {
       return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
                               _("Can't get entries of non-directory"));

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/update.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_serf/update.c Mon Mar 18 09:35:24 2013
@@ -1099,13 +1099,6 @@ handle_fetch(serf_request_t *request,
       val = serf_bucket_headers_get(hdrs, "Content-Type");
       info = fetch_ctx->info;
 
-      /* Open the file for editing. */
-      err = open_updated_file(info, FALSE, info->pool);
-      if (err)
-        {
-          return error_fetch(request, fetch_ctx, err);
-        }
-
       if (val && svn_cstring_casecmp(val, SVN_SVNDIFF_MIME_TYPE) == 0)
         {
           fetch_ctx->delta_stream =
@@ -1440,7 +1433,6 @@ static svn_error_t *
 handle_local_content(report_info_t *info,
                      apr_pool_t *scratch_pool)
 {
-  SVN_ERR(open_updated_file(info, TRUE, scratch_pool));
   SVN_ERR(svn_txdelta_send_stream(info->cached_contents, info->textdelta,
                                   info->textdelta_baton, NULL, scratch_pool));
   SVN_ERR(svn_stream_close(info->cached_contents));
@@ -1494,33 +1486,38 @@ fetch_file(report_context_t *ctx, report
     {
       svn_stream_t *contents = NULL;
 
-      if (ctx->sess->wc_callbacks->get_wc_contents
-          && (info->final_sha1_checksum || info->final_checksum))
+      /* Open the file for editing. */
+      SVN_ERR(open_updated_file(info, FALSE, info->pool));
+
+      if (info->textdelta == svn_delta_noop_window_handler)
         {
-          svn_error_t *err;
-          svn_checksum_t *checksum;
+          /* There is nobody looking for an actual stream.
+
+             Just report an empty stream instead of fetching
+             to be ingored data */
+          info->cached_contents = svn_stream_empty(info->pool);
+        }
+      else if (ctx->sess->wc_callbacks->get_wc_contents
+               && info->final_sha1_checksum)
+        {
+          svn_error_t *err = NULL;
+          svn_checksum_t *checksum = NULL;
          
-          /* Parse our checksum, preferring SHA1 to MD5. */
-          if (info->final_sha1_checksum)
-            {
-              err = svn_checksum_parse_hex(&checksum, svn_checksum_sha1,
-                                           info->final_sha1_checksum,
-                                           info->pool);
-            }
-          else if (info->final_checksum)
-            {
-              err = svn_checksum_parse_hex(&checksum, svn_checksum_md5,
-                                           info->final_checksum,
-                                           info->pool);
-            }
+          /* Parse the optional SHA1 checksum (1.7+) */
+          err = svn_checksum_parse_hex(&checksum, svn_checksum_sha1,
+                                       info->final_sha1_checksum,
+                                       info->pool);
 
           /* Okay so far?  Let's try to get a stream on some readily
              available matching content. */
-          if (!err)
+          if (!err && checksum)
             {
               err = ctx->sess->wc_callbacks->get_wc_contents(
                         ctx->sess->wc_callback_baton, &contents,
                         checksum, info->pool);
+
+              if (! err)
+                info->cached_contents = contents;
             }
 
           if (err)
@@ -1529,11 +1526,7 @@ fetch_file(report_context_t *ctx, report
                  errorful state, but this codepath is optional.  */
               svn_error_clear(err);
             }
-          else
-            {
-              info->cached_contents = contents;
-            }
-        }          
+        }
 
       /* If the working copy can provide cached contents for this
          file, we don't have to fetch them from the server. */
@@ -3410,9 +3403,12 @@ svn_ra_serf__do_switch(svn_ra_session_t 
                        const char *switch_target,
                        svn_depth_t depth,
                        const char *switch_url,
+                       svn_boolean_t send_copyfrom_args,
+                       svn_boolean_t ignore_ancestry,
                        const svn_delta_editor_t *switch_editor,
                        void *switch_baton,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
 
@@ -3420,8 +3416,12 @@ svn_ra_serf__do_switch(svn_ra_session_t 
                               revision_to_switch_to,
                               session->session_url.path,
                               switch_url, switch_target,
-                              depth, TRUE, TRUE, FALSE /* TODO(sussman) */,
-                              switch_editor, switch_baton, pool);
+                              depth,
+                              ignore_ancestry,
+                              TRUE /* text_deltas */,
+                              send_copyfrom_args,
+                              switch_editor, switch_baton,
+                              result_pool);
 }
 
 /* Helper svn_ra_serf__get_file(). Attempts to fetch file contents
@@ -3507,7 +3507,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
   svn_ra_serf__connection_t *conn;
   const char *fetch_url;
   apr_hash_t *fetch_props;
-  svn_kind_t res_kind;
+  svn_node_kind_t res_kind;
   const svn_ra_serf__dav_props_t *which_props;
 
   /* What connection should we go on? */
@@ -3553,7 +3553,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
 
   /* Verify that resource type is not collection. */
   SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, fetch_props));
-  if (res_kind != svn_kind_file)
+  if (res_kind != svn_node_file)
     {
       return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
                               _("Can't get text contents of a directory"));

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/client.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/client.c Mon Mar 18 09:35:24 2013
@@ -1394,14 +1394,20 @@ static svn_error_t *ra_svn_update(svn_ra
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_switch(svn_ra_session_t *session,
-                                  const svn_ra_reporter3_t **reporter,
-                                  void **report_baton, svn_revnum_t rev,
-                                  const char *target, svn_depth_t depth,
-                                  const char *switch_url,
-                                  const svn_delta_editor_t *update_editor,
-                                  void *update_baton, apr_pool_t *pool)
+static svn_error_t *
+ra_svn_switch(svn_ra_session_t *session,
+              const svn_ra_reporter3_t **reporter,
+              void **report_baton, svn_revnum_t rev,
+              const char *target, svn_depth_t depth,
+              const char *switch_url,
+              svn_boolean_t send_copyfrom_args,
+              svn_boolean_t ignore_ancestry,
+              const svn_delta_editor_t *update_editor,
+              void *update_baton,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
 {
+  apr_pool_t *pool = result_pool;
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
   svn_boolean_t recurse = DEPTH_TO_RECURSE(depth);
@@ -1409,7 +1415,8 @@ static svn_error_t *ra_svn_switch(svn_ra
   /* Tell the server we want to start a switch. */
   SVN_ERR(svn_ra_svn_write_templated_cmd(conn, pool, svn_ra_svn_cmd_switch,
                                          rev, target, recurse, switch_url,
-                                         svn_depth_to_word(depth)));
+                                         svn_depth_to_word(depth),
+                                         send_copyfrom_args, ignore_ancestry));
   SVN_ERR(handle_auth_request(sess_baton, pool));
 
   /* Fetch a reporter for the caller to drive.  The reporter will drive
@@ -2589,43 +2596,46 @@ ra_svn_replay_range(svn_ra_session_t *se
 }
 
 
-static svn_error_t *ra_svn_has_capability(svn_ra_session_t *session,
-                                          svn_boolean_t *has,
-                                          const char *capability,
-                                          apr_pool_t *pool)
+static svn_error_t *
+ra_svn_has_capability(svn_ra_session_t *session,
+                      svn_boolean_t *has,
+                      const char *capability,
+                      apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess = session->priv;
+  static const char* capabilities[][2] =
+  {
+      /* { ra capability string, svn:// wire capability string} */
+      {SVN_RA_CAPABILITY_DEPTH, SVN_RA_SVN_CAP_DEPTH},
+      {SVN_RA_CAPABILITY_MERGEINFO, SVN_RA_SVN_CAP_MERGEINFO},
+      {SVN_RA_CAPABILITY_LOG_REVPROPS, SVN_RA_SVN_CAP_LOG_REVPROPS},
+      {SVN_RA_CAPABILITY_PARTIAL_REPLAY, SVN_RA_SVN_CAP_PARTIAL_REPLAY},
+      {SVN_RA_CAPABILITY_COMMIT_REVPROPS, SVN_RA_SVN_CAP_COMMIT_REVPROPS},
+      {SVN_RA_CAPABILITY_ATOMIC_REVPROPS, SVN_RA_SVN_CAP_ATOMIC_REVPROPS},
+      {SVN_RA_CAPABILITY_INHERITED_PROPS, SVN_RA_SVN_CAP_INHERITED_PROPS},
+      {SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS,
+                                          SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS},
+      {SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE,
+                                       SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE},
+
+      {NULL, NULL} /* End of list marker */
+  };
+  int i;
 
   *has = FALSE;
 
-  if (strcmp(capability, SVN_RA_CAPABILITY_DEPTH) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_DEPTH);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_MERGEINFO);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_LOG_REVPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_LOG_REVPROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_PARTIAL_REPLAY) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn, SVN_RA_SVN_CAP_PARTIAL_REPLAY);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_COMMIT_REVPROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_ATOMIC_REVPROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_INHERITED_PROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_INHERITED_PROPS);
-  else if (strcmp(capability, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS) == 0)
-    *has = svn_ra_svn_has_capability(sess->conn,
-                                     SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS);
-  else  /* Don't know any other capabilities, so error. */
+  for (i = 0; capabilities[i][0]; i++)
     {
-      return svn_error_createf
-        (SVN_ERR_UNKNOWN_CAPABILITY, NULL,
-         _("Don't know anything about capability '%s'"), capability);
+      if (strcmp(capability, capabilities[i][0]) == 0)
+        {
+          *has = svn_ra_svn_has_capability(sess->conn, capabilities[i][1]);
+          return SVN_NO_ERROR;
+        }
     }
 
-  return SVN_NO_ERROR;
+  return svn_error_createf(SVN_ERR_UNKNOWN_CAPABILITY, NULL,
+                           _("Don't know anything about capability '%s'"),
+                           capability);
 }
 
 static svn_error_t *

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c Mon Mar 18 09:35:24 2013
@@ -964,6 +964,8 @@ vwrite_cmd_switch(svn_ra_svn_conn_t *con
   SVN_ERR(vwrite_tuple_boolean(conn, pool, ap));
   SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
   SVN_ERR(vwrite_tuple_word(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_boolean(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_boolean(conn, pool, ap));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c Mon Mar 18 09:35:24 2013
@@ -826,7 +826,7 @@ authz_retrieve_config_repo(svn_config_t 
     {
       if (!must_exist)
         {
-          SVN_ERR(svn_config_create(cfg_p, TRUE, scratch_pool));
+          SVN_ERR(svn_config_create(cfg_p, TRUE, result_pool));
           return SVN_NO_ERROR;
         }
       else
@@ -855,7 +855,7 @@ authz_retrieve_config_repo(svn_config_t 
   return SVN_NO_ERROR;
 }
 
-/* Given a PATH which might be a realative repo URL (^/), an absolute
+/* Given a PATH which might be a relative repo URL (^/), an absolute
  * local repo URL (file://), an absolute path outside of the repo
  * or a location in the Windows registry.
  *

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c Mon Mar 18 09:35:24 2013
@@ -850,14 +850,13 @@ fetch_props_func(apr_hash_t **props,
 }
 
 static svn_error_t *
-fetch_kind_func(svn_kind_t *kind,
+fetch_kind_func(svn_node_kind_t *kind,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
                 apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
-  svn_node_kind_t node_kind;
   svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
@@ -865,8 +864,7 @@ fetch_kind_func(svn_kind_t *kind,
 
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
-  SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
-  *kind = svn__kind_from_node_kind(node_kind, FALSE);
+  SVN_ERR(svn_fs_check_path(kind, fs_root, path, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1085,7 +1083,7 @@ add_symlink_cb(void *baton,
 static svn_error_t *
 add_absent_cb(void *baton,
               const char *relpath,
-              svn_kind_t kind,
+              svn_node_kind_t kind,
               svn_revnum_t replaces_rev,
               apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/dump.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/dump.c Mon Mar 18 09:35:24 2013
@@ -886,14 +886,13 @@ fetch_props_func(apr_hash_t **props,
 }
 
 static svn_error_t *
-fetch_kind_func(svn_kind_t *kind,
+fetch_kind_func(svn_node_kind_t *kind,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
                 apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
-  svn_node_kind_t node_kind;
   svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
@@ -901,8 +900,7 @@ fetch_kind_func(svn_kind_t *kind,
 
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
-  SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
-  *kind = svn__kind_from_node_kind(node_kind, FALSE);
+  SVN_ERR(svn_fs_check_path(kind, fs_root, path, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/replay.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/replay.c Mon Mar 18 09:35:24 2013
@@ -783,14 +783,13 @@ path_driver_cb_func(void **dir_baton,
 
 #ifdef USE_EV2_IMPL
 static svn_error_t *
-fetch_kind_func(svn_kind_t *kind,
+fetch_kind_func(svn_node_kind_t *kind,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
                 apr_pool_t *scratch_pool)
 {
   svn_fs_root_t *root = baton;
-  svn_node_kind_t node_kind;
   svn_fs_root_t *prev_root;
   svn_fs_t *fs = svn_fs_root_fs(root);
 
@@ -798,9 +797,8 @@ fetch_kind_func(svn_kind_t *kind,
     base_revision = svn_fs_revision_root_revision(root) - 1;
 
   SVN_ERR(svn_fs_revision_root(&prev_root, fs, base_revision, scratch_pool));
-  SVN_ERR(svn_fs_check_path(&node_kind, prev_root, path, scratch_pool));
+  SVN_ERR(svn_fs_check_path(kind, prev_root, path, scratch_pool));
 
-  *kind = svn__kind_from_node_kind(node_kind, FALSE);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/repos.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/repos.c Mon Mar 18 09:35:24 2013
@@ -1831,6 +1831,62 @@ svn_repos_recover4(const char *path,
   return SVN_NO_ERROR;
 }
 
+struct freeze_baton_t {
+  apr_array_header_t *paths;
+  int counter;
+  svn_error_t *(*freeze_body)(void *, apr_pool_t *);
+  void *baton;
+};
+
+static svn_error_t *
+multi_freeze(void *baton,
+             apr_pool_t *pool)
+{
+  struct freeze_baton_t *fb = baton;
+
+  if (fb->counter == fb->paths->nelts)
+    {
+      SVN_ERR(fb->freeze_body(fb->baton, pool));
+      return SVN_NO_ERROR;
+    }
+  else
+    {
+      /* Using a subpool as the only way to unlock the repos lock used
+         by BDB is to clear the pool used to take the lock. */
+      apr_pool_t *subpool = svn_pool_create(pool);
+      const char *path = APR_ARRAY_IDX(fb->paths, fb->counter, const char *);
+      svn_repos_t *repos;
+
+      ++fb->counter;
+
+      SVN_ERR(get_repos(&repos, path,
+                        TRUE  /* exclusive (only applies to BDB) */,
+                        FALSE /* non-blocking */,
+                        FALSE /* open-fs */,
+                        NULL, subpool));
+
+
+      if (strcmp(repos->fs_type, SVN_FS_TYPE_BDB) == 0)
+        {
+          svn_error_t *err = multi_freeze(fb, subpool);
+
+          svn_pool_destroy(subpool);
+
+          return err;
+        }
+      else
+        {
+          SVN_ERR(svn_fs_open(&repos->fs, repos->db_path, NULL, subpool));
+          SVN_ERR(svn_fs_freeze(svn_repos_fs(repos), multi_freeze, fb,
+                                subpool));
+        }
+
+      svn_pool_destroy(subpool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* For BDB we fall back on BDB's repos layer lock which means that the
    repository is unreadable while frozen.
 
@@ -1838,36 +1894,19 @@ svn_repos_recover4(const char *path,
    and an SQLite reserved lock which means the repository is readable
    while frozen. */
 svn_error_t *
-svn_repos_freeze(const char *path,
+svn_repos_freeze(apr_array_header_t *paths,
                  svn_error_t *(*freeze_body)(void *, apr_pool_t *),
                  void *baton,
                  apr_pool_t *pool)
 {
-  svn_repos_t *repos;
+  struct freeze_baton_t fb;
 
-  /* Using a subpool as the only way to unlock the repos lock used by
-     BDB is to clear the pool used to take the lock. */
-  apr_pool_t *subpool = svn_pool_create(pool);
-
-  SVN_ERR(get_repos(&repos, path,
-                    TRUE  /* exclusive */,
-                    FALSE /* non-blocking */,
-                    FALSE /* open-fs */,
-                    NULL, subpool));
-
-  if (strcmp(repos->fs_type, SVN_FS_TYPE_BDB) == 0)
-    {
-      svn_error_t *err = freeze_body(baton, subpool);
-      svn_pool_destroy(subpool);
-      return err;
-    }
-  else
-    {
-      SVN_ERR(svn_fs_open(&repos->fs, repos->db_path, NULL, subpool));
-      SVN_ERR(svn_fs_freeze(svn_repos_fs(repos), freeze_body, baton, subpool));
-    }
+  fb.paths = paths;
+  fb.counter = 0;
+  fb.freeze_body = freeze_body;
+  fb.baton = baton;
 
-  svn_pool_destroy(subpool);
+  SVN_ERR(multi_freeze(&fb, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/rev_hunt.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/rev_hunt.c Mon Mar 18 09:35:24 2013
@@ -532,7 +532,7 @@ check_ancestry_of_peg_path(svn_boolean_t
 {
   svn_fs_root_t *root;
   svn_fs_history_t *history;
-  const char *path;
+  const char *path = NULL;
   svn_revnum_t revision;
   apr_pool_t *lastpool, *currpool;
 
@@ -1252,17 +1252,18 @@ find_merged_revisions(apr_array_header_t
                       apr_hash_t *duplicate_path_revs,
                       svn_repos_authz_func_t authz_read_func,
                       void *authz_read_baton,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   const apr_array_header_t *old;
   apr_array_header_t *new_merged_path_revs;
   apr_pool_t *iterpool, *last_pool;
   apr_array_header_t *merged_path_revisions =
-    apr_array_make(pool, 0, sizeof(struct path_revision *));
+    apr_array_make(scratch_pool, 0, sizeof(struct path_revision *));
 
   old = mainline_path_revisions;
-  iterpool = svn_pool_create(pool);
-  last_pool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
+  last_pool = svn_pool_create(scratch_pool);
 
   do
     {
@@ -1325,8 +1326,8 @@ find_merged_revisions(apr_array_header_t
                                                      TRUE, TRUE,
                                                      duplicate_path_revs,
                                                      authz_read_func,
-                                                     authz_read_baton, pool,
-                                                     iterpool3));
+                                                     authz_read_baton,
+                                                     result_pool, iterpool3));
                 }
               svn_pool_destroy(iterpool3);
             }
@@ -1350,7 +1351,8 @@ find_merged_revisions(apr_array_header_t
         sizeof(struct path_revision *), compare_path_revisions);
 
   /* Copy to the output array. */
-  *merged_path_revisions_out = apr_array_copy(pool, merged_path_revisions);
+  *merged_path_revisions_out = apr_array_copy(result_pool,
+                                              merged_path_revisions);
 
   svn_pool_destroy(iterpool);
   svn_pool_destroy(last_pool);
@@ -1447,6 +1449,114 @@ send_path_revision(struct path_revision 
   return SVN_NO_ERROR;
 }
 
+/* Similar to svn_repos_get_file_revs2() but returns paths while walking
+   history instead of after collecting all history.
+
+   This allows implementing clients to immediately start processing and
+   stop when they got the information they need. (E.g. all or a specific set
+   of lines were modified) */
+static svn_error_t *
+get_file_revs_backwards(svn_repos_t *repos,
+                        const char *path,
+                        svn_revnum_t start,
+                        svn_revnum_t end,
+                        svn_repos_authz_func_t authz_read_func,
+                        void *authz_read_baton,
+                        svn_file_rev_handler_t handler,
+                        void *handler_baton,
+                        apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool, *last_pool;
+  svn_fs_history_t *history;
+  svn_fs_root_t *root;
+  svn_node_kind_t kind;
+  struct send_baton sb;
+
+  /* We switch between two pools while looping and so does the path-rev
+     handler for actually reported revisions. We do this as we
+     need just information from last iteration to be available. */
+
+  iterpool = svn_pool_create(scratch_pool);
+  last_pool = svn_pool_create(scratch_pool);
+  sb.iterpool = svn_pool_create(scratch_pool);
+  sb.last_pool = svn_pool_create(scratch_pool);
+
+  /* We want the first txdelta to be against the empty file. */
+  sb.last_root = NULL;
+  sb.last_path = NULL;
+
+  /* Create an empty hash table for the first property diff. */
+  sb.last_props = apr_hash_make(sb.last_pool);
+
+  /* The path had better be a file in this revision. */
+  SVN_ERR(svn_fs_revision_root(&root, repos->fs, end, scratch_pool));
+  SVN_ERR(svn_fs_check_path(&kind, root, path, scratch_pool));
+  if (kind != svn_node_file)
+    return svn_error_createf(SVN_ERR_FS_NOT_FILE, 
+                             NULL, _("'%s' is not a file in revision %ld"),
+                             path, end);
+
+  /* Open a history object. */
+  SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
+  while (1)
+    {
+      struct path_revision *path_rev;
+      svn_revnum_t tmp_revnum;
+      const char *tmp_path;
+
+      svn_pool_clear(iterpool);
+
+      /* Fetch the history object to walk through. */
+      SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
+      if (!history)
+        break;
+      SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
+                                      history, iterpool));
+
+      /* Check authorization. */
+      if (authz_read_func)
+        {
+          svn_boolean_t readable;
+          svn_fs_root_t *tmp_root;
+
+          SVN_ERR(svn_fs_revision_root(&tmp_root, repos->fs, tmp_revnum,
+                                       iterpool));
+          SVN_ERR(authz_read_func(&readable, tmp_root, tmp_path,
+                                  authz_read_baton, iterpool));
+          if (! readable)
+            break;
+        }
+
+      /* We didn't break, so we must really want this path-rev. */
+      path_rev = apr_palloc(iterpool, sizeof(*path_rev));
+      path_rev->path = tmp_path;
+      path_rev->revnum = tmp_revnum;
+      path_rev->merged = FALSE;
+
+      SVN_ERR(send_path_revision(path_rev, repos, &sb,
+                                 handler, handler_baton));
+
+      if (path_rev->revnum <= start)
+        break;
+
+      /* Swap pools. */
+      {
+        apr_pool_t *tmp_pool = iterpool;
+        iterpool = last_pool;
+        last_pool = tmp_pool;
+      }
+    }
+
+  svn_pool_destroy(iterpool);
+  svn_pool_destroy(last_pool);
+  svn_pool_destroy(sb.last_pool);
+  svn_pool_destroy(sb.iterpool);
+
+  return SVN_NO_ERROR;
+
+}
+
+
 /* We don't yet support sending revisions in reverse order; the caller wait
  * until we've traced back through the entire history, and then accept
  * them from oldest to youngest.  Someday this may change, but in the meantime,
@@ -1463,6 +1573,10 @@ send_path_revision(struct path_revision 
  *     oldest to youngest, interleaving as appropriate.  This is implemented
  *     similar to an insertion sort, but instead of inserting into another
  *     array, we just call the appropriate handler.
+ *
+ * 2013-02: Added a very simple reverse for mainline only changes. Before this,
+ *          this would return an error (path not found) or just the first
+ *          revision before end.
  */
 svn_error_t *
 svn_repos_get_file_revs2(svn_repos_t *repos,
@@ -1474,48 +1588,65 @@ svn_repos_get_file_revs2(svn_repos_t *re
                          void *authz_read_baton,
                          svn_file_rev_handler_t handler,
                          void *handler_baton,
-                         apr_pool_t *pool)
+                         apr_pool_t *scratch_pool)
 {
   apr_array_header_t *mainline_path_revisions, *merged_path_revisions;
   apr_hash_t *duplicate_path_revs;
   struct send_baton sb;
   int mainline_pos, merged_pos;
 
+  if (end < start)
+    {
+      if (include_merged_revisions)
+        return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+
+      return svn_error_trace(
+                      get_file_revs_backwards(repos, path,
+                                              end, start,
+                                              authz_read_func,
+                                              authz_read_baton,
+                                              handler,
+                                              handler_baton,
+                                              scratch_pool));
+    }
+
+  /* We switch between two pools while looping, since we need information from
+     the last iteration to be available. */
+  sb.iterpool = svn_pool_create(scratch_pool);
+  sb.last_pool = svn_pool_create(scratch_pool);
+
+  /* We want the first txdelta to be against the empty file. */
+  sb.last_root = NULL;
+  sb.last_path = NULL;
+
+  /* Create an empty hash table for the first property diff. */
+  sb.last_props = apr_hash_make(sb.last_pool);
+
+
   /* Get the revisions we are interested in. */
-  duplicate_path_revs = apr_hash_make(pool);
-  mainline_path_revisions = apr_array_make(pool, 0,
+  duplicate_path_revs = apr_hash_make(scratch_pool);
+  mainline_path_revisions = apr_array_make(scratch_pool, 100,
                                            sizeof(struct path_revision *));
   SVN_ERR(find_interesting_revisions(mainline_path_revisions, repos, path,
                                      start, end, include_merged_revisions,
                                      FALSE, duplicate_path_revs,
-                                     authz_read_func, authz_read_baton, pool,
-                                     pool));
+                                     authz_read_func, authz_read_baton,
+                                     scratch_pool, sb.iterpool));
 
   /* If we are including merged revisions, go get those, too. */
   if (include_merged_revisions)
     SVN_ERR(find_merged_revisions(&merged_path_revisions, start,
                                   mainline_path_revisions, repos,
                                   duplicate_path_revs, authz_read_func,
-                                  authz_read_baton, pool));
+                                  authz_read_baton,
+                                  scratch_pool, sb.iterpool));
   else
-    merged_path_revisions = apr_array_make(pool, 0,
+    merged_path_revisions = apr_array_make(scratch_pool, 0,
                                            sizeof(struct path_revision *));
 
   /* We must have at least one revision to get. */
   SVN_ERR_ASSERT(mainline_path_revisions->nelts > 0);
 
-  /* We switch betwwen two pools while looping, since we need information from
-     the last iteration to be available. */
-  sb.iterpool = svn_pool_create(pool);
-  sb.last_pool = svn_pool_create(pool);
-
-  /* We want the first txdelta to be against the empty file. */
-  sb.last_root = NULL;
-  sb.last_path = NULL;
-
-  /* Create an empty hash table for the first property diff. */
-  sb.last_props = apr_hash_make(sb.last_pool);
-
   /* Walk through both mainline and merged revisions, and send them in
      reverse chronological order, interleaving as appropriate. */
   mainline_pos = mainline_path_revisions->nelts - 1;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/config_file.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/config_file.c Mon Mar 18 09:35:24 2013
@@ -1175,8 +1175,18 @@ svn_config_ensure(const char *config_dir
         ""                                                                   NL
         "### Section for configuring working copies."                        NL
         "[working-copy]"                                                     NL
-        "### Set to true to enable exclusive SQLite locking.  Some clients"  NL
-        "### may not support exclusive locking."                             NL
+        "### Set to a list of the names of specific clients that should use" NL
+        "### exclusive SQLite locking of working copies.  This increases the"NL
+        "### performance of the client but prevents concurrent access by"    NL
+        "### other clients.  Third-party clients may also support this"      NL
+        "### option."                                                        NL
+        "### Possible values:"                                               NL
+        "###   svn                (the command line client)"                 NL
+        "# exclusive-locking-clients ="                                      NL
+        "### Set to true to enable exclusive SQLite locking of working"      NL
+        "### copies by all clients using the 1.8 APIs.  Enabling this may"   NL
+        "### cause some clients to fail to work properly. This does not have"NL
+        "### to be set for exclusive-locking-clients to work."               NL
         "# exclusive-locking = false"                                        NL;
 
       err = svn_io_file_open(&f, path,

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/dirent_uri.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/dirent_uri.c Mon Mar 18 09:35:24 2013
@@ -359,8 +359,24 @@ canonicalize(path_type_t type, const cha
             src = seg;
 
           /* Found a hostname, convert to lowercase and copy to dst. */
-          while (*src && (*src != '/') && (*src != ':'))
-            *(dst++) = canonicalize_to_lower((*src++));
+          if (*src == '[')
+            {
+             *(dst++) = *(src++); /* Copy '[' */
+
+              while (*src == ':'
+                     || (*src >= '0' && (*src <= '9'))
+                     || (*src >= 'a' && (*src <= 'f'))
+                     || (*src >= 'A' && (*src <= 'F')))
+                {
+                  *(dst++) = canonicalize_to_lower((*src++));
+                }
+
+              if (*src == ']')
+                *(dst++) = *(src++); /* Copy ']' */
+            }
+          else
+            while (*src && (*src != '/') && (*src != ':'))
+              *(dst++) = canonicalize_to_lower((*src++));
 
           if (*src == ':')
             {
@@ -1774,12 +1790,28 @@ svn_uri_is_canonical(const char *uri, ap
 
   /* Found a hostname, check that it's all lowercase. */
   ptr = seg;
-  while (*ptr && *ptr != '/' && *ptr != ':')
+
+  if (*ptr == '[')
     {
-      if (*ptr >= 'A' && *ptr <= 'Z')
+      ptr++;
+      while (*ptr == ':' 
+             || (*ptr >= '0' && *ptr <= '9')
+             || (*ptr >= 'a' && *ptr <= 'f'))
+        {
+          ptr++;
+        }
+
+      if (*ptr != ']')
         return FALSE;
       ptr++;
     }
+  else
+    while (*ptr && *ptr != '/' && *ptr != ':')
+      {
+        if (*ptr >= 'A' && *ptr <= 'Z')
+          return FALSE;
+        ptr++;
+      }
 
   /* Found a portnumber */
   if (*ptr == ':')

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/mergeinfo.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/mergeinfo.c Mon Mar 18 09:35:24 2013
@@ -1201,26 +1201,15 @@ range_swap_endpoints(svn_merge_range_t *
 svn_error_t *
 svn_rangelist_reverse(svn_rangelist_t *rangelist, apr_pool_t *pool)
 {
-  int i, swap_index;
-  svn_merge_range_t range;
-  for (i = 0; i < rangelist->nelts / 2; i++)
-    {
-      swap_index = rangelist->nelts - i - 1;
-      range = *APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
-      *APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *) =
-        *APR_ARRAY_IDX(rangelist, swap_index, svn_merge_range_t *);
-      *APR_ARRAY_IDX(rangelist, swap_index, svn_merge_range_t *) = range;
-      range_swap_endpoints(APR_ARRAY_IDX(rangelist, swap_index,
-                                         svn_merge_range_t *));
+  int i;
+
+  svn_sort__array_reverse(rangelist, pool);
+
+  for (i = 0; i < rangelist->nelts; i++)
+    {
       range_swap_endpoints(APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *));
     }
 
-  /* If there's an odd number of elements, we still need to swap the
-     end points of the remaining range. */
-  if (rangelist->nelts % 2 == 1)
-    range_swap_endpoints(APR_ARRAY_IDX(rangelist, rangelist->nelts / 2,
-                                       svn_merge_range_t *));
-
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/prompt.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/prompt.c Mon Mar 18 09:35:24 2013
@@ -32,6 +32,7 @@
 #include <apr_portable.h>
 
 #include "svn_cmdline.h"
+#include "svn_ctype.h"
 #include "svn_string.h"
 #include "svn_auth.h"
 #include "svn_error.h"
@@ -43,6 +44,7 @@
 #ifdef WIN32
 #include <conio.h>
 #elif defined(HAVE_TERMIOS_H)
+#include <signal.h>
 #include <termios.h>
 #endif
 
@@ -210,8 +212,7 @@ terminal_open(terminal_handle_t **termin
           attr.c_lflag &= ~(ISIG | ICANON);
           attr.c_cc[VMIN] = 1;          /* Read one byte at a time */
           attr.c_cc[VTIME] = 0;         /* No timeout, wait indefinitely */
-          if (noecho)
-            attr.c_lflag &= ~(ECHO);    /* Turn off echo */
+          attr.c_lflag &= ~(ECHO);      /* Turn off echo */
           if (0 == tcsetattr((*terminal)->osinfd, TCSAFLUSH, &attr))
             {
               (*terminal)->noecho = noecho;
@@ -269,6 +270,31 @@ terminal_puts(const char *string, termin
 #define TERMINAL_EOL   (TERMINAL_NONE + 2)   /* end of input/end of line */
 #define TERMINAL_EOF   (TERMINAL_NONE + 3)   /* end of file during input */
 
+/* Helper for terminal_getc: writes CH to OUTFD as a control char. */
+#ifndef WIN32
+static void
+echo_control_char(char ch, apr_file_t *outfd)
+{
+  if (svn_ctype_iscntrl(ch))
+    {
+      const char substitute = (ch < 32? '@' + ch : '?');
+      apr_file_putc('^', outfd);
+      apr_file_putc(substitute, outfd);
+    }
+  else if (svn_ctype_isprint(ch))
+    {
+      /* Pass printable characters unchanged. */
+      apr_file_putc(ch, outfd);
+    }
+  else
+    {
+      /* Everything else is strange. */
+      apr_file_putc('^', outfd);
+      apr_file_putc('!', outfd);
+    }
+}
+#endif /* WIN32 */
+
 /* Read one character or control code from TERMINAL, returning it in CODE.
    if CAN_ERASE and the input was a deletion, emit codes to erase the
    last character displayed on the terminal.
@@ -277,6 +303,7 @@ static svn_error_t *
 terminal_getc(int *code, terminal_handle_t *terminal,
               svn_boolean_t can_erase, apr_pool_t *pool)
 {
+  const svn_boolean_t echo = !terminal->noecho;
   apr_status_t status = APR_SUCCESS;
   char ch;
 
@@ -284,7 +311,6 @@ terminal_getc(int *code, terminal_handle
   if (!terminal->infd)
     {
       /* See terminal_open; we're using Console I/O. */
-      const svn_boolean_t echo = !terminal->noecho;
 
       /*  The following was hoisted from APR's getpass for Windows. */
       int concode = _getch();
@@ -359,18 +385,49 @@ terminal_getc(int *code, terminal_handle
         return svn_error_wrap_apr(status, _("Can't read from terminal"));
 
       if (ch == attr->c_cc[VINTR] || ch == attr->c_cc[VQUIT])
-        return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+        {
+          /* Break */
+          echo_control_char(ch, terminal->outfd);
+          return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+        }
       else if (ch == '\r' || ch == '\n' || ch == attr->c_cc[VEOL])
-        *code = TERMINAL_EOL;
-      else if (ch == '\b'
-               || ch == attr->c_cc[VERASE] || ch == attr->c_cc[VKILL])
-        *code = TERMINAL_DEL;
+        {
+          /* Newline */
+          *code = TERMINAL_EOL;
+          apr_file_putc('\n', terminal->outfd);
+        }
+      else if (ch == '\b' || ch == attr->c_cc[VERASE])
+        {
+          /* Delete */
+          *code = TERMINAL_DEL;
+          if (can_erase)
+            {
+              apr_file_putc('\b', terminal->outfd);
+              apr_file_putc(' ', terminal->outfd);
+              apr_file_putc('\b', terminal->outfd);
+            }
+        }
       else if (ch == attr->c_cc[VEOF])
-        *code = TERMINAL_EOF;
+        {
+          /* End of input */
+          *code = TERMINAL_EOF;
+          echo_control_char(ch, terminal->outfd);
+        }
+      else if (ch == attr->c_cc[VSUSP])
+        {
+          /* Suspend */
+          *code = TERMINAL_NONE;
+          kill(0, SIGTSTP);
+        }
       else if (!apr_iscntrl(ch))
-        *code = (int)(unsigned char)ch;
+        {
+          /* Normal character */
+          *code = (int)(unsigned char)ch;
+          apr_file_putc((echo ? ch : '*'), terminal->outfd);
+        }
       else
         {
+          /* Ignored character */
           *code = TERMINAL_NONE;
           apr_file_putc('\a', terminal->outfd);
         }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/sorts.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/sorts.c Mon Mar 18 09:35:24 2013
@@ -270,3 +270,39 @@ svn_sort__array_delete(apr_array_header_
       arr->nelts -= elements_to_delete;
     }
 }
+
+void
+svn_sort__array_reverse(apr_array_header_t *array,
+                        apr_pool_t *scratch_pool)
+{
+  int i;
+
+  if (array->elt_size == sizeof(void *))
+    {
+      for (i = 0; i < array->nelts / 2; i++)
+        {
+          int swap_index = array->nelts - i - 1;
+          void *tmp = APR_ARRAY_IDX(array, i, void *);
+
+          APR_ARRAY_IDX(array, i, void *) =
+            APR_ARRAY_IDX(array, swap_index, void *);
+          APR_ARRAY_IDX(array, swap_index, void *) = tmp;
+        }
+    }
+  else
+    {
+      apr_size_t sz = array->elt_size;
+      char *tmp = apr_palloc(scratch_pool, sz);
+
+      for (i = 0; i < array->nelts / 2; i++)
+        {
+          int swap_index = array->nelts - i - 1;
+          char *x = array->elts + (sz * i);
+          char *y = array->elts + (sz * swap_index);
+
+          memcpy(tmp, x, sz);
+          memcpy(x, y, sz);
+          memcpy(y, tmp, sz);
+        }
+    }
+}

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/sqlite.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/sqlite.c Mon Mar 18 09:35:24 2013
@@ -140,8 +140,9 @@ struct svn_sqlite__value_t
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
     return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                             NULL, "sqlite: %s",                 \
-                             sqlite3_errmsg((db)->db3));         \
+                             NULL, "sqlite: %s (S%d)",             \
+                             sqlite3_errmsg((db)->db3),           \
+                             sqlite_err__temp);                   \
 } while (0)
 
 #define SQLITE_ERR_MSG(x, msg) do                                \
@@ -149,7 +150,8 @@ struct svn_sqlite__value_t
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
     return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                             NULL, "sqlite: %s", (msg));         \
+                             NULL, "sqlite: %s (S%d)", (msg),     \
+                             sqlite_err__temp);                  \
 } while (0)
 
 
@@ -171,8 +173,9 @@ exec_sql2(svn_sqlite__db_t *db, const ch
   if (sqlite_err != SQLITE_OK && sqlite_err != ignored_err)
     {
       svn_error_t *err = svn_error_createf(SQLITE_ERROR_CODE(sqlite_err), NULL,
-                                           _("sqlite: %s, executing statement '%s'"),
-                                           err_msg, sql);
+                                           _("sqlite: %s (S%d),"
+                                             " executing statement '%s'"),
+                                           err_msg, sqlite_err, sql);
       sqlite3_free(err_msg);
       return err;
     }
@@ -289,7 +292,8 @@ svn_sqlite__step(svn_boolean_t *got_row,
       svn_error_t *err1, *err2;
 
       err1 = svn_error_createf(SQLITE_ERROR_CODE(sqlite_result), NULL,
-                               "sqlite: %s", sqlite3_errmsg(stmt->db->db3));
+                               "sqlite: %s (S%d)",
+                               sqlite3_errmsg(stmt->db->db3), sqlite_result);
       err2 = svn_sqlite__reset(stmt);
       return svn_error_compose_create(err1, err2);
     }
@@ -739,8 +743,8 @@ init_sqlite(void *baton, apr_pool_t *poo
   {
     int err = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
     if (err != SQLITE_OK && err != SQLITE_MISUSE)
-      return svn_error_create(SQLITE_ERROR_CODE(err), NULL,
-                              _("Could not configure SQLite"));
+      return svn_error_createf(SQLITE_ERROR_CODE(err), NULL,
+                               _("Could not configure SQLite (S%d)"), err);
   }
   SQLITE_ERR_MSG(sqlite3_initialize(), _("Could not initialize SQLite"));
 
@@ -778,7 +782,7 @@ internal_open(sqlite3 **db3, const char 
        occurs (except for out-of-memory); thus, we can safely use it to
        extract an error message and construct an svn_error_t. */
     {
-      /* We'd like to use SQLITE_ERR_MSG here, but we can't since it would
+      /* We'd like to use SQLITE_ERR here, but we can't since it would
          just return an error and leave the database open.  So, we need to
          do this manually. */
       /* ### SQLITE_CANTOPEN */
@@ -792,8 +796,7 @@ internal_open(sqlite3 **db3, const char 
              error than the close error at this point. */
           sqlite3_close(*db3);
 
-          return svn_error_createf(SQLITE_ERROR_CODE(err_code), NULL,
-                                   "sqlite: %s: '%s'", msg, path);
+          SQLITE_ERR_MSG(err_code, msg);
         }
     }
   }
@@ -863,7 +866,7 @@ close_apr(void *data)
     }
 
   if (result != SQLITE_OK)
-    return SQLITE_ERROR_CODE(result);
+    return SQLITE_ERROR_CODE(result); /* ### lossy */
 
   db->db3 = NULL;
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/subst.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/subst.c Mon Mar 18 09:35:24 2013
@@ -1743,7 +1743,12 @@ svn_subst_copy_and_translate4(const char
     }
 
   /* Now that dst_tmp contains the translated data, do the atomic rename. */
-  return svn_error_trace(svn_io_file_rename(dst_tmp, dst, pool));
+  SVN_ERR(svn_io_file_rename(dst_tmp, dst, pool));
+
+  /* Preserve the source file's permission bits. */
+  SVN_ERR(svn_io_copy_perms(src, dst, pool));
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/sysinfo.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/sysinfo.c Mon Mar 18 09:35:24 2013
@@ -28,6 +28,7 @@
 #define PSAPI_VERSION 1
 #include <windows.h>
 #include <psapi.h>
+#include <Ws2tcpip.h>
 #endif
 
 #define APR_WANT_STRFUNC

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/types.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/types.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/types.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/types.c Mon Mar 18 09:35:24 2013
@@ -121,37 +121,6 @@ svn_depth_from_word(const char *word)
   return svn_depth_unknown;
 }
 
-svn_node_kind_t
-svn__node_kind_from_kind(svn_kind_t kind)
-{
-  switch (kind)
-    {
-    case svn_kind_unknown:  return svn_node_unknown;
-    case svn_kind_none:     return svn_node_none;
-    case svn_kind_file:     return svn_node_file;
-    case svn_kind_dir:      return svn_node_dir;
-    case svn_kind_symlink:  return svn_node_file;
-    default: SVN_ERR_MALFUNCTION_NO_RETURN();
-    }
-}
-
-svn_kind_t
-svn__kind_from_node_kind(svn_node_kind_t kind,
-                         svn_boolean_t is_symlink)
-{
-  if (is_symlink)
-    return svn_kind_symlink;
-
-  switch (kind)
-    {
-    case svn_node_unknown:  return svn_kind_unknown;
-    case svn_node_none:     return svn_kind_none;
-    case svn_node_file:     return svn_kind_file;
-    case svn_node_dir:      return svn_kind_dir;
-    default: SVN_ERR_MALFUNCTION_NO_RETURN();
-    }
-}
-
 const char *
 svn_node_kind_to_word(svn_node_kind_t kind)
 {
@@ -163,6 +132,8 @@ svn_node_kind_to_word(svn_node_kind_t ki
       return "file";
     case svn_node_dir:
       return "dir";
+    case svn_node_symlink:
+      return "symlink";
     case svn_node_unknown:
     default:
       return "unknown";
@@ -182,6 +153,8 @@ svn_node_kind_from_word(const char *word
     return svn_node_file;
   else if (strcmp(word, "dir") == 0)
     return svn_node_dir;
+  else if (strcmp(word, "symlink") == 0)
+    return svn_node_symlink;
   else
     /* This also handles word == "unknown" */
     return svn_node_unknown;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/utf_validate.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/utf_validate.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/utf_validate.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/utf_validate.c Mon Mar 18 09:35:24 2013
@@ -352,6 +352,10 @@ svn_boolean_t
 svn_utf__cstring_is_valid(const char *data)
 {
   int state = FSM_START;
+
+  if (!data)
+    return FALSE;
+
   data = first_non_fsm_start_char_cstring(data);
 
   while (*data)
@@ -368,6 +372,10 @@ svn_utf__is_valid(const char *data, apr_
 {
   const char *end = data + len;
   int state = FSM_START;
+
+  if (!data)
+    return FALSE;
+
   data = first_non_fsm_start_char(data, len);
 
   while (data < end)

Modified: subversion/branches/verify-keep-going/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_subr/win32_crashrpt.c?rev=1457684&r1=1457683&r2=1457684&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_subr/win32_crashrpt.c Mon Mar 18 09:35:24 2013
@@ -33,6 +33,7 @@ typedef int win32_crashrpt__dummy;
 #include <direct.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 
 #include "svn_version.h"