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 2017/10/31 09:40:00 UTC

svn commit: r1813860 [8/8] - in /subversion/branches/shelve-checkpoint: ./ build/ build/generator/ notes/commit-access-templates/ subversion/bindings/javahl/native/ subversion/bindings/swig/include/ subversion/include/ subversion/include/private/ subve...

Modified: subversion/branches/shelve-checkpoint/subversion/tests/libsvn_client/conflicts-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/libsvn_client/conflicts-test.c?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/tests/libsvn_client/conflicts-test.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/tests/libsvn_client/conflicts-test.c Tue Oct 31 09:39:59 2017
@@ -162,6 +162,7 @@ assert_text_conflict_options(svn_client_
 /* Some paths we'll care about. */
 static const char *trunk_path = "A";
 static const char *branch_path = "A_branch";
+static const char *branch2_path = "A_branch2";
 static const char *new_file_name = "newfile.txt";
 static const char *new_file_name_branch = "newfile-on-branch.txt";
 static const char *deleted_file_name = "mu";
@@ -4578,89 +4579,6 @@ test_update_incoming_added_dir_merge2(co
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-test_cherry_pick_post_move_edit(const svn_test_opts_t *opts,
-                                apr_pool_t *pool)
-{
-  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
-  const char *trunk_url;
-  svn_opt_revision_t peg_rev;
-  apr_array_header_t *ranges_to_merge;
-  svn_opt_revision_range_t merge_range;
-  svn_client_ctx_t *ctx;
-  svn_client_conflict_t *conflict;
-  svn_boolean_t tree_conflicted;
-
-  SVN_ERR(svn_test__sandbox_create(b,
-                                   "test_cherry_pick_post_move_edit",
-                                   opts, pool));
-
-  SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
-  /* Create a copy of node "A". */
-  SVN_ERR(sbox_wc_copy(b, "A", "A1"));
-  SVN_ERR(sbox_wc_commit(b, "")); /* r2 */
-  /* On "trunk", move the file mu. */
-  SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved"));
-  SVN_ERR(sbox_wc_commit(b, "")); /* r3 */
-  /* On "trunk", edit mu-moved. This will be r4, which we'll cherry-pick. */
-  SVN_ERR(sbox_file_write(b, "A/mu-moved", "Modified content.\n"));
-  SVN_ERR(sbox_wc_commit(b, "")); /* r4 */
-  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
-
-  /* Perform a cherry-pick merge of r4 from A to A1. */
-  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
-  trunk_url = apr_pstrcat(b->pool, b->repos_url, "/A", SVN_VA_NULL);
-  peg_rev.kind = svn_opt_revision_number;
-  peg_rev.value.number = 4;
-  merge_range.start.kind = svn_opt_revision_number;
-  merge_range.start.value.number = 3;
-  merge_range.end.kind = svn_opt_revision_number;
-  merge_range.end.value.number = 4;
-  ranges_to_merge = apr_array_make(b->pool, 1,
-                                   sizeof(svn_opt_revision_range_t *));
-  APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = &merge_range;
-  /* This should raise a "local delete or move vs incoming edit" conflict. */
-  SVN_ERR(svn_client_merge_peg5(trunk_url, ranges_to_merge, &peg_rev,
-                                sbox_wc_path(b, "A1"), svn_depth_infinity,
-                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
-                                NULL, ctx, b->pool));
-
-  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"),
-                                  ctx, b->pool, b->pool));
-  SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted,
-                                             conflict, b->pool, b->pool));
-  SVN_TEST_ASSERT(tree_conflicted);
-  {
-    svn_client_conflict_option_id_t expected_opts[] = {
-      svn_client_conflict_option_postpone,
-      svn_client_conflict_option_accept_current_wc_state,
-      -1 /* end of list */
-    };
-    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
-                                         b->pool));
-  }
-
-  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
-  {
-    svn_client_conflict_option_id_t expected_opts[] = {
-      svn_client_conflict_option_postpone,
-      svn_client_conflict_option_accept_current_wc_state,
-      svn_client_conflict_option_local_move_file_text_merge,
-      -1 /* end of list */
-    };
-    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
-                                         b->pool));
-  }
-
-  /* Try to resolve the conflict. */
-  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
-            conflict,
-            svn_client_conflict_option_local_move_file_text_merge,
-            ctx, b->pool));
-
-  return SVN_NO_ERROR;
-}
-
 /* Regression test for chrash fixed in r1780259. */
 static svn_error_t *
 test_cherry_pick_moved_file_with_propdel(const svn_test_opts_t *opts,
@@ -4976,6 +4894,288 @@ test_merge_incoming_move_file_text_merge
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_cherry_pick_post_move_edit(const svn_test_opts_t *opts,
+                                apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  const char *trunk_url;
+  svn_opt_revision_t peg_rev;
+  apr_array_header_t *ranges_to_merge;
+  svn_opt_revision_range_t merge_range;
+  svn_client_ctx_t *ctx;
+  svn_client_conflict_t *conflict;
+  svn_boolean_t tree_conflicted;
+  svn_stringbuf_t *buf;
+
+  SVN_ERR(svn_test__sandbox_create(b,
+                                   "test_cherry_pick_post_move_edit",
+                                   opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+  /* Create a copy of node "A". */
+  SVN_ERR(sbox_wc_copy(b, "A", "A1"));
+  SVN_ERR(sbox_wc_commit(b, "")); /* r2 */
+  /* On "trunk", move the file mu. */
+  SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved"));
+  SVN_ERR(sbox_wc_commit(b, "")); /* r3 */
+  /* On "trunk", edit mu-moved. This will be r4. */
+  SVN_ERR(sbox_file_write(b, "A/mu-moved", "Modified content." APR_EOL_STR));
+  SVN_ERR(sbox_wc_commit(b, "")); /* r4 */
+  /* On "trunk", edit mu-moved. This will be r5, which we'll cherry-pick. */
+  SVN_ERR(sbox_file_write(b, "A/mu-moved",
+                          "More modified content." APR_EOL_STR));
+  SVN_ERR(sbox_wc_commit(b, "")); /* r5 */
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+
+  /* Perform a cherry-pick merge of r5 from A to A1. */
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  trunk_url = apr_pstrcat(b->pool, b->repos_url, "/A", SVN_VA_NULL);
+  peg_rev.kind = svn_opt_revision_number;
+  peg_rev.value.number = 5;
+  merge_range.start.kind = svn_opt_revision_number;
+  merge_range.start.value.number = 4;
+  merge_range.end.kind = svn_opt_revision_number;
+  merge_range.end.value.number = 5;
+  ranges_to_merge = apr_array_make(b->pool, 1,
+                                   sizeof(svn_opt_revision_range_t *));
+  APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = &merge_range;
+  /* This should raise a "local delete or move vs incoming edit" conflict. */
+  SVN_ERR(svn_client_merge_peg5(trunk_url, ranges_to_merge, &peg_rev,
+                                sbox_wc_path(b, "A1"), svn_depth_infinity,
+                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+                                NULL, ctx, b->pool));
+
+  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"),
+                                  ctx, b->pool, b->pool));
+  SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted,
+                                             conflict, b->pool, b->pool));
+  SVN_TEST_ASSERT(tree_conflicted);
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
+                                         b->pool));
+  }
+
+  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_local_move_file_text_merge,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
+                                         b->pool));
+  }
+
+  /* Try to resolve the conflict. */
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict,
+            svn_client_conflict_option_local_move_file_text_merge,
+            ctx, b->pool));
+
+  /* The node "A1/mu-moved" should no longer exist. */
+  SVN_TEST_ASSERT_ERROR(svn_client_conflict_get(&conflict,
+                                                sbox_wc_path(b, "A1/mu-moved"),
+                                                ctx, pool, pool),
+                        SVN_ERR_WC_PATH_NOT_FOUND);
+
+  /* And "A1/mu" should have expected contents. */
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A1/mu"), pool));
+  SVN_TEST_STRING_ASSERT(buf->data, "More modified content." APR_EOL_STR);
+
+  return SVN_NO_ERROR;
+}
+
+/* A helper function which prepares a working copy for the tests below. */
+static svn_error_t *
+create_wc_with_incoming_delete_dir_conflict_across_branches(
+  svn_test__sandbox_t *b)
+{
+  svn_client_ctx_t *ctx;
+  const char *trunk_url;
+  const char *branch_url;
+  svn_opt_revision_t opt_rev;
+  const char *deleted_path;
+  const char *deleted_child_path;
+  const char *move_target_path;
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b));
+
+  /* Create a branch of node "A". */
+  SVN_ERR(sbox_wc_copy(b, trunk_path, branch_path));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Create a second branch ("branch2") of the first branch. */
+  SVN_ERR(sbox_wc_copy(b, branch_path, branch2_path));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Move a directory on the trunk. */
+  deleted_path = svn_relpath_join(trunk_path, deleted_dir_name, b->pool);
+  move_target_path = svn_relpath_join(trunk_path, new_dir_name, b->pool);
+  SVN_ERR(sbox_wc_move(b, deleted_path, move_target_path));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  /* Modify a file in that directory on branch2. */
+  deleted_child_path = svn_relpath_join(branch2_path,
+                                        svn_relpath_join(deleted_dir_name,
+                                                         deleted_dir_child,
+                                                         b->pool),
+                                        b->pool);
+  SVN_ERR(sbox_file_write(b, deleted_child_path,
+                          modified_file_on_branch_content));
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  opt_rev.kind = svn_opt_revision_head;
+  opt_rev.value.number = SVN_INVALID_REVNUM;
+  trunk_url = apr_pstrcat(b->pool, b->repos_url, "/", trunk_path,
+                          SVN_VA_NULL);
+  branch_url = apr_pstrcat(b->pool, b->repos_url, "/", branch_path,
+                          SVN_VA_NULL);
+
+  /* Commit modification and run a merge from the trunk to the branch.
+   * This merge should not raise a conflict. */
+  SVN_ERR(sbox_wc_commit(b, ""));
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+  SVN_ERR(svn_client_merge_peg5(trunk_url, NULL, &opt_rev,
+                                sbox_wc_path(b, branch_path),
+                                svn_depth_infinity,
+                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+                                NULL, ctx, b->pool));
+
+  /* Commit merge result end run a merge from branch to branch2. */
+  SVN_ERR(sbox_wc_commit(b, ""));
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+
+  /* This should raise an "incoming delete vs local edit" tree conflict. */
+  SVN_ERR(svn_client_merge_peg5(branch_url, NULL, &opt_rev,
+                                sbox_wc_path(b, branch2_path),
+                                svn_depth_infinity,
+                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+                                NULL, ctx, b->pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_merge_incoming_move_dir_across_branches(const svn_test_opts_t *opts,
+                                             apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  const char *deleted_path;
+  const char *moved_to_path;
+  const char *child_path;
+  svn_client_conflict_t *conflict;
+  struct status_baton sb;
+  struct svn_client_status_t *status;
+  svn_stringbuf_t *buf;
+  svn_opt_revision_t opt_rev;
+  apr_array_header_t *options;
+  svn_client_conflict_option_t *option;
+  apr_array_header_t *possible_moved_to_abspaths;
+
+  SVN_ERR(svn_test__sandbox_create(b,
+                                   "merge_incoming_move_dir accross branches",
+                                   opts, pool));
+
+  SVN_ERR(create_wc_with_incoming_delete_dir_conflict_across_branches(b));
+
+  deleted_path = svn_relpath_join(branch2_path, deleted_dir_name, b->pool);
+  moved_to_path = svn_relpath_join(branch2_path, new_dir_name, b->pool);
+
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, deleted_path),
+                                  ctx, b->pool, b->pool));
+  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool));
+
+  /* Check possible move destinations for the directory. */
+  SVN_ERR(svn_client_conflict_tree_get_resolution_options(&options, conflict,
+                                                          ctx, b->pool,
+                                                          b->pool));
+  option = svn_client_conflict_option_find_by_id(
+             options, svn_client_conflict_option_incoming_move_dir_merge);
+  SVN_TEST_ASSERT(option != NULL);
+
+  SVN_ERR(svn_client_conflict_option_get_moved_to_abspath_candidates(
+            &possible_moved_to_abspaths, option, b->pool, b->pool));
+
+  /* The resolver finds two possible destinations for the moved folder:
+   *
+   *   Possible working copy destinations for moved-away 'A_branch/B' are:
+   *    (1): 'A_branch2/newdir'
+   *    (2): 'A_branch/newdir'
+   *   Only one destination can be a move; the others are copies.
+   */
+  SVN_TEST_INT_ASSERT(possible_moved_to_abspaths->nelts, 2);
+  SVN_TEST_STRING_ASSERT(
+    APR_ARRAY_IDX(possible_moved_to_abspaths, 0, const char *),
+    sbox_wc_path(b, moved_to_path));
+  SVN_TEST_STRING_ASSERT(
+    APR_ARRAY_IDX(possible_moved_to_abspaths, 1, const char *),
+    sbox_wc_path(b, svn_relpath_join(branch_path, new_dir_name, b->pool)));
+
+  /* Resolve the tree conflict. */
+  SVN_ERR(svn_client_conflict_option_set_moved_to_abspath(option, 0,
+                                                          ctx, b->pool));
+  SVN_ERR(svn_client_conflict_tree_resolve(conflict, option, ctx, b->pool));
+
+  /* Ensure that the moved-away directory has the expected status. */
+  sb.result_pool = b->pool;
+  opt_rev.kind = svn_opt_revision_working;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, deleted_path),
+                             &opt_rev, svn_depth_empty, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_dir);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(!status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_deleted);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(!status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(status->moved_to_abspath,
+                         sbox_wc_path(b, moved_to_path));
+
+  /* Ensure that the moved-here directory has the expected status. */
+  sb.result_pool = b->pool;
+  opt_rev.kind = svn_opt_revision_working;
+  SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, moved_to_path),
+                             &opt_rev, svn_depth_empty, TRUE, TRUE,
+                             TRUE, TRUE, FALSE, TRUE, NULL,
+                             status_func, &sb, b->pool));
+  status = sb.status;
+  SVN_TEST_ASSERT(status->kind == svn_node_dir);
+  SVN_TEST_ASSERT(status->versioned);
+  SVN_TEST_ASSERT(!status->conflicted);
+  SVN_TEST_ASSERT(status->node_status == svn_wc_status_added);
+  SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+  SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+  SVN_TEST_ASSERT(status->copied);
+  SVN_TEST_ASSERT(!status->switched);
+  SVN_TEST_ASSERT(!status->file_external);
+  SVN_TEST_STRING_ASSERT(status->moved_from_abspath,
+                         sbox_wc_path(b, deleted_path));
+  SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+  /* Ensure that the edited file has the expected content. */
+  child_path = svn_relpath_join(moved_to_path, deleted_dir_child,
+                                b->pool);
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, child_path),
+                                   b->pool));
+  SVN_TEST_STRING_ASSERT(buf->data, modified_file_on_branch_content);
+
+  return SVN_NO_ERROR;
+}
+
 /* ========================================================================== */
 
 
@@ -5064,6 +5264,8 @@ static struct svn_test_descriptor_t test
                        "merge incoming move file merge with native eols"),
     SVN_TEST_OPTS_XFAIL(test_cherry_pick_post_move_edit,
                         "cherry-pick edit from moved file"),
+    SVN_TEST_OPTS_PASS(test_merge_incoming_move_dir_across_branches,
+                        "merge incoming dir move across branches"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/shelve-checkpoint/subversion/tests/libsvn_repos/dump-load-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/libsvn_repos/dump-load-test.c?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/tests/libsvn_repos/dump-load-test.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/tests/libsvn_repos/dump-load-test.c Tue Oct 31 09:39:59 2017
@@ -79,7 +79,7 @@ test_dump_bad_props(svn_stringbuf_t **du
   SVN_ERR(svn_repos_dump_fs4(repos, stream, start_rev, end_rev,
                              FALSE, FALSE, TRUE, TRUE,
                              notify_func, notify_baton,
-                             NULL, NULL,
+                             NULL, NULL, NULL, NULL,
                              pool));
   svn_stream_close(stream);
 
@@ -120,13 +120,14 @@ test_load_bad_props(svn_stringbuf_t *dum
   svn_revnum_t youngest_rev;
   svn_string_t *loaded_prop_val;
 
-  SVN_ERR(svn_repos_load_fs5(repos, stream,
+  SVN_ERR(svn_repos_load_fs6(repos, stream,
                              SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
                              svn_repos_load_uuid_default,
                              parent_fspath,
                              FALSE, FALSE, /*use_*_commit_hook*/
                              validate_props,
                              FALSE /*ignore_dates*/,
+                             FALSE /*normalize_props*/,
                              notify_func, notify_baton,
                              NULL, NULL, /*cancellation*/
                              pool));

Modified: subversion/branches/shelve-checkpoint/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/libsvn_subr/string-test.c?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/tests/libsvn_subr/string-test.c Tue Oct 31 09:39:59 2017
@@ -1013,6 +1013,60 @@ test_stringbuf_set(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_cstring_join(apr_pool_t *pool)
+{
+  apr_array_header_t *arr;
+
+  {
+    arr = apr_array_make(pool, 0, sizeof(const char *));
+
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", FALSE, pool), "");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", TRUE, pool), "");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", FALSE, pool), "");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", TRUE, pool), "");
+  }
+
+  {
+    arr = apr_array_make(pool, 0, sizeof(const char *));
+    APR_ARRAY_PUSH(arr, const char *) = "";
+
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", FALSE, pool), "");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", TRUE, pool), "");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", FALSE, pool), "");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", TRUE, pool), ";");
+  }
+
+  {
+    arr = apr_array_make(pool, 0, sizeof(const char *));
+    APR_ARRAY_PUSH(arr, const char *) = "ab";
+    APR_ARRAY_PUSH(arr, const char *) = "cd";
+
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", FALSE, pool), "abcd");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", TRUE, pool), "abcd");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", FALSE, pool), "ab;cd");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", TRUE, pool), "ab;cd;");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "//", FALSE, pool), "ab//cd");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "//", TRUE, pool), "ab//cd//");
+  }
+
+  {
+    arr = apr_array_make(pool, 0, sizeof(const char *));
+    APR_ARRAY_PUSH(arr, const char *) = "";
+    APR_ARRAY_PUSH(arr, const char *) = "ab";
+    APR_ARRAY_PUSH(arr, const char *) = "";
+
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", FALSE, pool), "ab");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "", TRUE, pool), "ab");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", FALSE, pool), ";ab;");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, ";", TRUE, pool), ";ab;;");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "//", FALSE, pool), "//ab//");
+    SVN_TEST_STRING_ASSERT(svn_cstring_join2(arr, "//", TRUE, pool), "//ab////");
+  }
+
+  return SVN_NO_ERROR;
+}
+
 /*
    ====================================================================
    If you add a new test to this file, update this array.
@@ -1095,6 +1149,8 @@ static struct svn_test_descriptor_t test
                    "test svn_stringbuf_leftchop"),
     SVN_TEST_PASS2(test_stringbuf_set,
                    "test svn_stringbuf_set()"),
+    SVN_TEST_PASS2(test_cstring_join,
+                   "test svn_cstring_join2()"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/utils.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/utils.c?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/utils.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/utils.c Tue Oct 31 09:39:59 2017
@@ -139,12 +139,9 @@ svn_test__create_fake_wc(const char *wc_
    * refer to it over its lifetime. */
   my_statements = apr_palloc(scratch_pool, 7 * sizeof(const char *));
   my_statements[0] = statements[STMT_CREATE_SCHEMA];
-  my_statements[1] = statements[STMT_CREATE_NODES];
-  my_statements[2] = statements[STMT_CREATE_NODES_TRIGGERS];
-  my_statements[3] = statements[STMT_CREATE_EXTERNALS];
-  my_statements[4] = statements[STMT_INSTALL_SCHEMA_STATISTICS];
-  my_statements[5] = extra_statements;
-  my_statements[6] = NULL;
+  my_statements[1] = statements[STMT_INSTALL_SCHEMA_STATISTICS];
+  my_statements[2] = extra_statements;
+  my_statements[3] = NULL;
 
   /* Create fake-wc/SUBDIR/.svn/ for placing the metadata. */
   SVN_ERR(svn_io_make_dir_recursively(dotsvn_abspath, scratch_pool));

Modified: subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/tests/libsvn_wc/wc-queries-test.c Tue Oct 31 09:39:59 2017
@@ -70,9 +70,6 @@ static const int schema_statements[] =
 {
   /* Usual tables */
   STMT_CREATE_SCHEMA,
-  STMT_CREATE_NODES,
-  STMT_CREATE_NODES_TRIGGERS,
-  STMT_CREATE_EXTERNALS,
   STMT_INSTALL_SCHEMA_STATISTICS,
   /* Memory tables */
   STMT_CREATE_TARGETS_LIST,

Modified: subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh (original)
+++ subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh Tue Oct 31 09:39:59 2017
@@ -53,7 +53,7 @@ mount | grep "^/dev/disk[0-9][0-9]* on $
 
     # Make sure we strip trailing spaces from the result of older
     # versions of hduitil.
-    device=$(echo $(hdiutil attach -nomount ram://1000000))
+    device=$(echo $(hdiutil attach -nomount ram://2000000))
     newfs_hfs -M 0700 -v "$1" "${device}"
     hdiutil mountvol "${device}"
 

Modified: subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/setenv.sh
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/setenv.sh?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/setenv.sh (original)
+++ subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/setenv.sh Tue Oct 31 09:39:59 2017
@@ -29,6 +29,7 @@
 ##     SVNBB_APR_20_DEV         Path of APR-2.0
 ##     SVNBB_JUNIT              The path of the junit.jar
 ##     SVNBB_PARALLEL           Optional: parallelization; defaults to 2
+##     SVNBB_PYTHON3ENV         Optional: Python 3 virtual environment
 ##
 ## The invoking script will set local variable named ${scripts} that
 ## is the absolute path the parent of this file.
@@ -48,6 +49,7 @@ export SVNBB_APR_15
 export SVNBB_APR_20_DEV
 export SVNBB_JUNIT
 export SVNBB_PARALLEL
+export SVNBB_PYTHON3ENV
 
 
 # Set the absolute source path

Modified: subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/svncheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/svncheck.sh?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/svncheck.sh (original)
+++ subversion/branches/shelve-checkpoint/tools/buildbot/slaves/svn-x64-macosx/svncheck.sh Tue Oct 31 09:39:59 2017
@@ -63,6 +63,7 @@ scripts=$(cd $(dirname "$0") && pwd)
 . ${scripts}/setenv.sh
 
 # Parse arguments to find out which tests we should run
+use_python3=false
 check_local=false
 check_svn=false
 check_dav=false
@@ -74,6 +75,7 @@ check_bdb=false
 
 while [ ! -z "$1" ]; do
     case "$1" in
+        python3) use_python3=true;;
         local)   check_local=true;;
         svn)     check_svn=true;;
         dav)     check_dav=true;;
@@ -87,6 +89,8 @@ while [ ! -z "$1" ]; do
     shift
 done
 
+${use_python3} && test -n "${SVNBB_PYTHON3ENV}" && . ${SVNBB_PYTHON3ENV}/bin/activate
+
 ${check_local} && check_tests local
 ${check_svn} && check_tests svn
 ${check_dav} && check_tests dav

Modified: subversion/branches/shelve-checkpoint/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/client-side/bash_completion?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/client-side/bash_completion (original)
+++ subversion/branches/shelve-checkpoint/tools/client-side/bash_completion Tue Oct 31 09:39:59 2017
@@ -1030,10 +1030,10 @@ _svn()
 		cmdOpts="$qOpts"
 		;;
 	shelve)
-		cmdOpts="$qOpts --delete --list --dry-run $nOpts --targets $cOpts"
+		cmdOpts="$qOpts --keep-local --delete --list $qOpts --dry-run --depth --targets $cOpts"
 		;;
 	unshelve)
-		cmdOpts="$qOpts --keep --dry-run"
+		cmdOpts="$qOpts --keep-shelved --list $qOpts --dry-run"
 		;;
 	shelves)
 		cmdOpts="$qOpts"
@@ -1120,9 +1120,9 @@ _svnadmin ()
 	cur=${COMP_WORDS[COMP_CWORD]}
 
 	# Possible expansions, without pure-prefix abbreviations such as "h".
-	cmds='crashtest create delrevprop deltify dump freeze help hotcopy \
-	      info list-dblogs \
-	      list-unused-dblogs load lock lslocks lstxns pack recover rmlocks \
+	cmds='crashtest create delrevprop deltify dump dump-revprops freeze \
+	      help hotcopy info list-dblogs list-unused-dblogs \
+	      load load-revprops lock lslocks lstxns pack recover rmlocks \
 	      rmtxns setlog setrevprop setuuid unlock upgrade verify --version'
 
 	if [[ $COMP_CWORD -eq 1 ]] ; then
@@ -1133,7 +1133,7 @@ _svnadmin ()
 	# options that require a parameter
 	# note: continued lines must end '|' continuing lines must start '|'
 	optsParam="-r|--revision|--parent-dir|--fs-type|-M|--memory-cache-size"
-	optsParam="$optsParam|-F|--file"
+	optsParam="$optsParam|-F|--file|--exclude|--include"
 
 	# if not typing an option, or if the previous option required a
 	# parameter, then fallback on ordinary filename expansion
@@ -1156,7 +1156,8 @@ _svnadmin ()
 		;;
 	dump)
 		cmdOpts="-r --revision --incremental -q --quiet --deltas \
-		         -M --memory-cache-size -F --file"
+		         -M --memory-cache-size -F --file \
+		         --exclude --include --pattern"
 		;;
 	freeze)
 		cmdOpts="-F --file"
@@ -1171,7 +1172,7 @@ _svnadmin ()
 		cmdOpts="--ignore-uuid --force-uuid --parent-dir -q --quiet \
 		         --use-pre-commit-hook --use-post-commit-hook \
 		         --bypass-prop-validation -M --memory-cache-size \
-		         --no-flush-to-disk -F --file"
+		         --no-flush-to-disk --normalize-props -F --file"
 		;;
 	lstxns)
         	cmdOpts="-r --revision"
@@ -1273,9 +1274,9 @@ _svndumpfilter ()
 	cmdOpts=
 	case ${COMP_WORDS[1]} in
 	exclude|include)
-		cmdOpts="--drop-empty-revs --renumber-revs
+		cmdOpts="--drop-empty-revs --drop-all-empty-revs --renumber-revs
 		         --skip-missing-merge-sources --targets
-		         --preserve-revprops --quiet"
+		         --preserve-revprops --quiet --pattern"
 		;;
 	help|h|\?)
 		cmdOpts="$cmds"

Modified: subversion/branches/shelve-checkpoint/tools/dev/svnmover/svnmover.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/dev/svnmover/svnmover.c?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/dev/svnmover/svnmover.c (original)
+++ subversion/branches/shelve-checkpoint/tools/dev/svnmover/svnmover.c Tue Oct 31 09:39:59 2017
@@ -3921,7 +3921,8 @@ execute(svnmover_wc_t *wc,
           wc->list_of_commands
             = apr_psprintf(pool, "%s%s\n",
                            wc->list_of_commands ? wc->list_of_commands : "",
-                           svn_cstring_join(action->action_args, " ", pool));
+                           svn_cstring_join2(action->action_args, " ",
+                                             TRUE, pool));
         }
     }
   svn_pool_destroy(iterpool);

Modified: subversion/branches/shelve-checkpoint/tools/dev/unix-build/Makefile.svn
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/dev/unix-build/Makefile.svn?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/dev/unix-build/Makefile.svn (original)
+++ subversion/branches/shelve-checkpoint/tools/dev/unix-build/Makefile.svn Tue Oct 31 09:39:59 2017
@@ -50,6 +50,10 @@ PWD		= $(shell pwd)
 UNAME		= $(shell uname)
 RUBY		= $(shell which ruby 2>/dev/null)
 ifeq ($(RUBY),)
+RUBY		= $(shell which ruby24 2>/dev/null)
+ifeq ($(RUBY),)
+RUBY		= $(shell which ruby23 2>/dev/null)
+ifeq ($(RUBY),)
 RUBY		= $(shell which ruby22 2>/dev/null)
 ifeq ($(RUBY),)
 RUBY		= $(shell which ruby21 2>/dev/null)
@@ -64,6 +68,8 @@ endif # 1.9
 endif # 2.0
 endif # 2.1
 endif # 2.2
+endif # 2.3
+endif # 2.4
 
 TAG		?= none
 ifeq ($(TAG),none)
@@ -95,7 +101,7 @@ SERF_OLD_VER	= 0.3.1
 CYRUS_SASL_VER	= 2.1.25
 SQLITE_VER	= 3160200
 LIBMAGIC_VER	= 5.30
-RUBY_VER	= 2.1.10
+RUBY_VER	= 2.4.2
 BZ2_VER	= 1.0.6
 PYTHON_VER	= 2.7.13
 JUNIT_VER	= 4.10
@@ -125,7 +131,7 @@ SHA256_${NEON_DIST} = db0bd8cdec329b48f5
 SHA256_${CYRUS_SASL_DIST} = 418c16e6240a4f9b637cbe3d62937b9675627bad27c622191d47de8686fe24fe
 SHA256_${SQLITE_DIST} = 65cc0c3e9366f50c0679c5ccd31432cea894bc4a3e8947dabab88c8693263615
 SHA256_${LIBMAGIC_DIST} = 694c2432e5240187524c9e7cf1ec6acc77b47a0e19554d34c14773e43dbbf214
-SHA256_${RUBY_DIST} = fb2e454d7a5e5a39eb54db0ec666f53eeb6edc593d1d2b970ae4d150b831dd20
+SHA256_${RUBY_DIST} = 93b9e75e00b262bc4def6b26b7ae8717efc252c47154abb7392e54357e6c8c9c
 SHA256_${BZ2_DIST} = a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd
 SHA256_${PYTHON_DIST} = a4f05a0720ce0fd92626f0278b6b433eee9a6173ddf2bced7957dfb599a5ece1
 SHA256_${JUNIT_DIST} = 36a747ca1e0b86f6ea88055b8723bb87030d627766da6288bf077afdeeb0f75a
@@ -174,7 +180,7 @@ SERF_OLD_URL	= https://svn.apache.org/re
 SQLITE_URL	= https://www.sqlite.org/2017/$(SQLITE_DIST)
 CYRUS_SASL_URL	= ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/$(CYRUS_SASL_DIST)
 LIBMAGIC_URL	= ftp://ftp.astron.com/pub/file/$(LIBMAGIC_DIST)
-RUBY_URL	= https://cache.ruby-lang.org/pub/ruby/2.1/$(RUBY_DIST)
+RUBY_URL	= https://cache.ruby-lang.org/pub/ruby/2.4/$(RUBY_DIST)
 BZ2_URL		= http://bzip.org/$(BZ2_VER)/$(BZ2_DIST)
 PYTHON_URL	= https://python.org/ftp/python/$(PYTHON_VER)/$(PYTHON_DIST)
 JUNIT_URL	= https://downloads.sourceforge.net/project/junit/junit/$(JUNIT_VER)/$(JUNIT_DIST)
@@ -1111,6 +1117,7 @@ $(RUBY_OBJDIR)/.retrieved: $(DISTDIR)/$(
 	$(call do_check_sha256,$(RUBY_DIST))
 	[ -d $(RUBY_OBJDIR) ] || mkdir -p $(RUBY_OBJDIR)
 	tar -C $(SRCDIR) -zxf $(DISTDIR)/$(RUBY_DIST)
+	-which ghead && sed -i -e "s/head -c/ghead -c/" $(RUBY_SRCDIR)/configure
 	touch $@
 
 ifeq ($(THREADING),yes)

Modified: subversion/branches/shelve-checkpoint/tools/dist/templates/rc-release-ann.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/dist/templates/rc-release-ann.ezt?rev=1813860&r1=1813859&r2=1813860&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/dist/templates/rc-release-ann.ezt (original)
+++ subversion/branches/shelve-checkpoint/tools/dist/templates/rc-release-ann.ezt Tue Oct 31 09:39:59 2017
@@ -37,7 +37,7 @@ A pre-release means the Subversion devel
 is ready for widespread testing by the community.  There are known issues
 (and unknown ones!), so please use it at your own risk, though we do
 encourage people to test this release thoroughly.  Of particular note, please
-remember than persistent data, such as the working copy or repository
+remember that persistent data, such as the working copy or repository
 formats may change before the final release, and there may not be an
 upgrade path from the pre-releases to the final.