subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1220893 [18/19] - in /subversion/branches/fs-py: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ subversion/bindings/javahl/native/ s...
Date Mon, 19 Dec 2011 18:49:43 GMT
Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.cfg
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.cfg?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.cfg (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/config-test.cfg Mon Dec 19 18:49:34 2011
@@ -41,6 +41,9 @@ h=  %(unterminated
 # Multiple expansions
 i=%(a)s %(b)s
 
+[UpperCaseSection]
+a=Aa
+
 [booleans]
 true1 = true
 true2 = Yes

Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/dirent_uri-test.c Mon Dec 19 18:49:34 2011
@@ -1441,28 +1441,6 @@ static const testcase_ancestor_t relpath
     { "X:foo",          "X:bar",            NULL },
   };
 
-static svn_error_t *
-test_relpath_is_ancestor(apr_pool_t *pool)
-{
-  const testcase_ancestor_t *t;
-
-  for (t = relpath_ancestor_tests;
-       t < relpath_ancestor_tests + COUNT_OF(relpath_ancestor_tests);
-       t++)
-    {
-      svn_boolean_t retval;
-
-      retval = svn_relpath__is_ancestor(t->path1, t->path2);
-      if (!!t->result != retval)
-        return svn_error_createf
-          (SVN_ERR_TEST_FAILED, NULL,
-           "svn_relpath_is_ancestor (%s, %s) returned %s instead of %s",
-           t->path1, t->path2, retval ? "TRUE" : "FALSE",
-           t->result ? "TRUE" : "FALSE");
-    }
-  return SVN_NO_ERROR;
-}
-
 static const testcase_ancestor_t uri_ancestor_tests[] =
   {
     { "http://test",    "http://test",      "" },
@@ -1860,133 +1838,6 @@ test_dirent_is_child(apr_pool_t *pool)
 }
 
 static svn_error_t *
-test_relpath_is_child(apr_pool_t *pool)
-{
-  int i, j;
-
-  static const char * const paths[] = {
-    "",
-    "foo",
-    "foo/bar",
-    "foo/bars",
-    "foo/baz",
-    "foo/bar/baz",
-    "flu/blar/blaz",
-    "foo/bar/baz/bing/boom",
-    ".foo",
-    ":",
-    "foo2",
-    "food",
-    "bar",
-    "baz",
-    "ba",
-    "bad"
-    };
-
-  /* Maximum number of path[] items for all platforms */
-#define MAX_PATHS 32
-
-  static const char * const
-    remainders[COUNT_OF(paths)][MAX_PATHS] = {
-    { 0, "foo", "foo/bar", "foo/bars", "foo/baz", "foo/bar/baz",
-      "flu/blar/blaz", "foo/bar/baz/bing/boom", ".foo", ":", "foo2", "food",
-      "bar", "baz", "ba", "bad" },
-    { 0, 0, "bar", "bars", "baz", "bar/baz", 0, "bar/baz/bing/boom", 0, 0, 0,
-      0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, "baz", 0, "baz/bing/boom", 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, "bing/boom", 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-  };
-
-  for (i = 0; i < COUNT_OF(paths); i++)
-    {
-      for (j = 0; j < COUNT_OF(paths); j++)
-        {
-          const char *remainder;
-
-          remainder = svn_dirent_is_child(paths[i], paths[j], pool);
-
-          if (strcmp(paths[j], "foodbar") == 0)
-            SVN_ERR_MALFUNCTION();
-
-          if (((remainder) && (! remainders[i][j]))
-              || ((! remainder) && (remainders[i][j]))
-              || (remainder && strcmp(remainder, remainders[i][j])))
-            return svn_error_createf
-              (SVN_ERR_TEST_FAILED, NULL,
-               "svn_relpath_is_child(%s, %s) returned '%s' instead of '%s'",
-               paths[i], paths[j],
-               remainder ? remainder : "(null)",
-               remainders[i][j] ? remainders[i][j] : "(null)" );
-        }
-    }
-
-#undef NUM_TEST_PATHS
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-test_uri_is_child(apr_pool_t *pool)
-{
-  int i, j;
-
-  static const char * const paths[] = {
-    "http://foo/bar",
-    "http://foo/bar%20bell",
-    "http://foo/baz",
-    "http://foo",
-    "http://f",
-    "file://foo/bar",
-    "file://foo/bar/baz%20bol",
-    };
-
-  static const char * const
-    remainders[COUNT_OF(paths)][COUNT_OF(paths)] = {
-    { 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0 },
-    { "bar", "bar bell", "baz", 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, 0 },
-    { 0, 0, 0, 0, 0, 0, "baz bol" },
-    { 0, 0, 0, 0, 0, 0, 0 },
-  };
-
-  for (i = 0; i < COUNT_OF(paths); i++)
-    {
-      for (j = 0; j < COUNT_OF(paths); j++)
-        {
-          const char *remainder;
-
-          remainder = svn_uri__is_child(paths[i], paths[j], pool);
-
-          if (((remainder) && (! remainders[i][j]))
-              || ((! remainder) && (remainders[i][j]))
-              || (remainder && strcmp(remainder, remainders[i][j])))
-            return svn_error_createf
-              (SVN_ERR_TEST_FAILED, NULL,
-               "svn_uri_is_child (%s, %s) [%d,%d] "
-               "returned '%s' instead of '%s'",
-               paths[i], paths[j], i, j,
-               remainder ? remainder : "(null)",
-               remainders[i][j] ? remainders[i][j] : "(null)" );
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
 test_dirent_get_absolute(apr_pool_t *pool)
 {
   int i;
@@ -2686,7 +2537,7 @@ test_fspath_join(apr_pool_t *pool)
 }
 
 static svn_error_t *
-test_fspath_is_child(apr_pool_t *pool)
+test_fspath_skip_ancestor(apr_pool_t *pool)
 {
   int i, j;
 
@@ -2701,12 +2552,12 @@ test_fspath_is_child(apr_pool_t *pool)
 
   static const char * const
     remainders[COUNT_OF(paths)][COUNT_OF(paths)] = {
-    { 0,  "f",  "foo",  "foo/bar",  "foo/bars", "foo/bar/baz" },
-    { 0,  0,    0,      0,          0,          0             },
-    { 0,  0,    0,      "bar",      "bars",     "bar/baz"     },
-    { 0,  0,    0,      0,          0,          "baz"         },
-    { 0,  0,    0,      0,          0,          0             },
-    { 0,  0,    0,      0,          0,          0             },
+    { "", "f",  "foo",  "foo/bar",  "foo/bars", "foo/bar/baz" },
+    { 0,  "",   0,      0,          0,          0             },
+    { 0,  0,    "",     "bar",      "bars",     "bar/baz"     },
+    { 0,  0,    0,      "",         0,          "baz"         },
+    { 0,  0,    0,      0,          "",         0             },
+    { 0,  0,    0,      0,          0,          ""            },
   };
 
   for (i = 0; i < COUNT_OF(paths); i++)
@@ -2714,7 +2565,7 @@ test_fspath_is_child(apr_pool_t *pool)
       for (j = 0; j < COUNT_OF(paths); j++)
         {
           const char *remainder
-            = svn_fspath__is_child(paths[i], paths[j], pool);
+            = svn_fspath__skip_ancestor(paths[i], paths[j]);
 
           SVN_TEST_STRING_ASSERT(remainder, remainders[i][j]);
         }
@@ -2861,14 +2712,8 @@ struct svn_test_descriptor_t test_funcs[
                    "test svn_uri_get_longest_ancestor"),
     SVN_TEST_PASS2(test_dirent_is_child,
                    "test svn_dirent_is_child"),
-    SVN_TEST_PASS2(test_relpath_is_child,
-                   "test svn_relpath_is_child"),
-    SVN_TEST_PASS2(test_uri_is_child,
-                   "test svn_uri_is_child"),
     SVN_TEST_PASS2(test_dirent_is_ancestor,
                    "test svn_dirent_is_ancestor"),
-    SVN_TEST_PASS2(test_relpath_is_ancestor,
-                   "test svn_relpath_is_ancestor"),
     SVN_TEST_PASS2(test_uri_is_ancestor,
                    "test svn_uri_is_ancestor"),
     SVN_TEST_PASS2(test_dirent_skip_ancestor,
@@ -2905,8 +2750,8 @@ struct svn_test_descriptor_t test_funcs[
                    "test svn_fspath__is_canonical"),
     SVN_TEST_PASS2(test_fspath_join,
                    "test svn_fspath__join"),
-    SVN_TEST_PASS2(test_fspath_is_child,
-                   "test svn_fspath__is_child"),
+    SVN_TEST_PASS2(test_fspath_skip_ancestor,
+                   "test svn_fspath__skip_ancestor"),
     SVN_TEST_PASS2(test_fspath_dirname_basename_split,
                    "test svn_fspath__dirname/basename/split"),
     SVN_TEST_PASS2(test_fspath_get_longest_ancestor,

Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/mergeinfo-test.c Mon Dec 19 18:49:34 2011
@@ -483,8 +483,7 @@ test_rangelist_reverse(apr_pool_t *pool)
   svn_merge_range_t expected_rangelist[3] =
     { {10, 9, TRUE}, {7, 4, TRUE}, {3, 2, TRUE} };
 
-  SVN_ERR(svn_mergeinfo_parse(&info1, "/trunk: 3,5-7,10", pool));
-  rangelist = apr_hash_get(info1, "/trunk", APR_HASH_KEY_STRING);
+  SVN_ERR(svn_rangelist__parse(&rangelist, "3,5-7,10", pool));
 
   SVN_ERR(svn_rangelist_reverse(rangelist, pool));
 
@@ -506,11 +505,9 @@ test_rangelist_intersect(apr_pool_t *poo
     { {0, 1, TRUE}, {2, 4, TRUE}, {11, 12, TRUE}, {30, 32, FALSE},
       {39, 42, TRUE} };
 
-  SVN_ERR(svn_mergeinfo_parse(&info1, "/trunk: 1-6,12-16,30-32*,40-42", pool));
-  SVN_ERR(svn_mergeinfo_parse(&info2, "/trunk: 1,3-4*,7,9,11-12,31-34*,38-44",
-                              pool));
-  rangelist1 = apr_hash_get(info1, "/trunk", APR_HASH_KEY_STRING);
-  rangelist2 = apr_hash_get(info2, "/trunk", APR_HASH_KEY_STRING);
+  SVN_ERR(svn_rangelist__parse(&rangelist1, "1-6,12-16,30-32*,40-42", pool));
+  SVN_ERR(svn_rangelist__parse(&rangelist2, "1,3-4*,7,9,11-12,31-34*,38-44",
+                               pool));
 
   /* Check the intersection while considering inheritance twice, reversing
      the order of the rangelist arguments on the second call to
@@ -605,6 +602,7 @@ test_merge_mergeinfo(apr_pool_t *pool)
   struct mergeinfo_merge_path_range
     {
       const char *path;
+      int expected_n;
       svn_merge_range_t expected_rngs[MAX_NBR_MERGEINFO_RANGES];
     };
 
@@ -627,75 +625,75 @@ test_merge_mergeinfo(apr_pool_t *pool)
       /* One path, intersecting inheritable ranges */
       { "/trunk: 5-10",
         "/trunk: 6", 1,
-        { {"/trunk", { {4, 10, TRUE} } } } },
+        { {"/trunk", 1, { {4, 10, TRUE} } } } },
 
       /* One path, intersecting non-inheritable ranges */
       { "/trunk: 5-10*",
         "/trunk: 6*", 1,
-        { {"/trunk", { {4, 10, FALSE} } } } },
+        { {"/trunk", 1, { {4, 10, FALSE} } } } },
 
       /* One path, intersecting ranges with different inheritability */
       { "/trunk: 5-10",
         "/trunk: 6*", 1,
-        { {"/trunk", { {4, 10, TRUE} } } } },
+        { {"/trunk", 1, { {4, 10, TRUE} } } } },
 
       /* One path, intersecting ranges with different inheritability */
       { "/trunk: 5-10*",
         "/trunk: 6", 1,
-        { {"/trunk", { {4, 5, FALSE}, {5, 6, TRUE}, {6, 10, FALSE} } } } },
+        { {"/trunk", 3, { {4, 5, FALSE}, {5, 6, TRUE}, {6, 10, FALSE} } } } },
 
       /* Adjacent ranges all inheritable ranges */
       { "/trunk: 1,3,5-11,13",
         "/trunk: 2,4,12,14-22", 1,
-         { {"/trunk", { {0, 22, TRUE} } } } },
+        { {"/trunk", 1, { {0, 22, TRUE} } } } },
 
       /* Adjacent ranges all non-inheritable ranges */
       { "/trunk: 1*,3*,5-11*,13*",
         "/trunk: 2*,4*,12*,14-22*", 1,
-         { {"/trunk", { {0, 22, FALSE} } } } },
+        { {"/trunk", 1, { {0, 22, FALSE} } } } },
 
       /* Adjacent ranges differing inheritability */
       { "/trunk: 1*,3*,5-11*,13*",
         "/trunk: 2,4,12,14-22", 1,
-         { {"/trunk", { { 0,  1, FALSE}, { 1,  2, TRUE},
-                        { 2,  3, FALSE}, { 3,  4, TRUE},
-                        { 4, 11, FALSE}, {11, 12, TRUE},
-                        {12, 13, FALSE}, {13, 22, TRUE} } } } },
+        { {"/trunk", 8, { { 0,  1, FALSE}, { 1,  2, TRUE},
+                          { 2,  3, FALSE}, { 3,  4, TRUE},
+                          { 4, 11, FALSE}, {11, 12, TRUE},
+                          {12, 13, FALSE}, {13, 22, TRUE} } } } },
 
       /* Adjacent ranges differing inheritability */
       { "/trunk: 1,3,5-11,13",
         "/trunk: 2*,4*,12*,14-22*", 1,
-         { {"/trunk", { { 0,  1, TRUE}, { 1,  2, FALSE},
-                        { 2,  3, TRUE}, { 3,  4, FALSE},
-                        { 4, 11, TRUE}, {11, 12, FALSE},
-                        {12, 13, TRUE}, {13, 22, FALSE} } } } },
+        { {"/trunk", 8, { { 0,  1, TRUE}, { 1,  2, FALSE},
+                          { 2,  3, TRUE}, { 3,  4, FALSE},
+                          { 4, 11, TRUE}, {11, 12, FALSE},
+                          {12, 13, TRUE}, {13, 22, FALSE} } } } },
 
       /* Two paths all inheritable ranges */
       { "/trunk::1: 3,5,7-9,10,11,13,14\n/fred:8-10",
         "/trunk::1: 1-4,6\n/fred:9-12", 2,
-        { {"/trunk::1", { {0, 11, TRUE}, {12, 14, TRUE} } },
-          {"/fred",  { {7, 12, TRUE} } } } },
+        { {"/trunk::1", 2, { {0, 11, TRUE}, {12, 14, TRUE} } },
+          {"/fred",     1, { {7, 12, TRUE} } } } },
 
       /* Two paths all non-inheritable ranges */
       { "/trunk: 3*,5*,7-9*,10*,11*,13*,14*\n/fred:8-10*",
         "/trunk: 1-4*,6*\n/fred:9-12*", 2,
-        { {"/trunk", { {0, 11, FALSE}, {12, 14, FALSE} } },
-          {"/fred",  { {7, 12, FALSE} } } } },
+        { {"/trunk", 2, { {0, 11, FALSE}, {12, 14, FALSE} } },
+          {"/fred",  1, { {7, 12, FALSE} } } } },
 
       /* Two paths mixed inheritability */
       { "/trunk: 3,5*,7-9,10,11*,13,14\n/fred:8-10",
         "/trunk: 1-4,6\n/fred:9-12*", 2,
-        { {"/trunk", { { 0,  4, TRUE }, { 4,  5, FALSE}, {5, 10, TRUE},
-                       {10, 11, FALSE}, {12, 14, TRUE } } },
-          {"/fred",  { { 7, 10, TRUE }, {10, 12, FALSE} } } } },
+        { {"/trunk", 5, { { 0,  4, TRUE }, { 4,  5, FALSE}, {5, 10, TRUE},
+                          {10, 11, FALSE}, {12, 14, TRUE } } },
+          {"/fred",  2, { { 7, 10, TRUE }, {10, 12, FALSE} } } } },
 
       /* A slew of different paths but no ranges to be merged */
       { "/trunk: 3,5-9*\n/betty: 2-4",
         "/fred: 1-18\n/:barney: 1,3-43", 4,
-        { {"/trunk",   { {2,  3, TRUE}, {4,  9, FALSE} } },
-          {"/betty",   { {1,  4, TRUE} } },
-          {"/:barney", { {0,  1, TRUE}, {2, 43, TRUE} } },
-          {"/fred",    { {0, 18, TRUE} } } } }
+        { {"/trunk",   2, { {2,  3, TRUE}, {4,  9, FALSE} } },
+          {"/betty",   1, { {1,  4, TRUE} } },
+          {"/:barney", 2, { {0,  1, TRUE}, {2, 43, TRUE} } },
+          {"/fred",    1, { {0, 18, TRUE} } } } }
     };
 
   for (i = 0; i < NBR_MERGEINFO_MERGES; i++)
@@ -730,36 +728,18 @@ test_merge_mergeinfo(apr_pool_t *pool)
 
       for (j = 0; j < mergeinfo[i].expected_paths; j++)
         {
-          int k;
           apr_array_header_t *rangelist =
             apr_hash_get(info1, mergeinfo[i].path_rngs[j].path,
                          APR_HASH_KEY_STRING);
           if (!rangelist)
             return fail(pool, "Missing path '%s' in merged mergeinfo",
-                        mergeinfo[i].path_rngs->path);
-          for (k = 0; k < rangelist->nelts; k++)
-            {
-              svn_merge_range_t *ranges =
-                APR_ARRAY_IDX(rangelist, k, svn_merge_range_t *);
-              if (ranges->start
-                    != mergeinfo[i].path_rngs[j].expected_rngs[k].start
-                  || ranges->end
-                    != mergeinfo[i].path_rngs[j].expected_rngs[k].end
-                  || ranges->inheritable
-                    != mergeinfo[i].path_rngs[j].expected_rngs[k].inheritable)
-                return fail(
-                  pool,
-                  "Range'%i-%i%s' not found in merged mergeinfo",
-                  mergeinfo[i].path_rngs->expected_rngs[k].start,
-                  mergeinfo[i].path_rngs->expected_rngs[k].end,
-                  mergeinfo[i].path_rngs->expected_rngs[k].inheritable
-                  ? "" : "*");
-            }
-          /* Were more ranges expected? */
-          if (k < MAX_NBR_MERGEINFO_RANGES
-              && mergeinfo[i].path_rngs[j].expected_rngs[k].start != 0)
-            return fail(pool,
-                        "Not all expected ranges found in merged mergeinfo");
+                        mergeinfo[i].path_rngs[j].path);
+          SVN_ERR(verify_ranges_match(
+                    rangelist,
+                    mergeinfo[i].path_rngs[j].expected_rngs,
+                    mergeinfo[i].path_rngs[j].expected_n,
+                    apr_psprintf(pool, "svn_rangelist_merge case %i:%i", i, j),
+                    "merge", pool));
         }
     }
 
@@ -800,39 +780,39 @@ test_remove_rangelist(apr_pool_t *pool)
   struct rangelist_remove_test_data test_data[SIZE_OF_RANGE_REMOVE_TEST_ARRAY] =
     {
       /* Eraser is a proper subset of whiteboard */
-      {"/A: 1-44",  "/A: 5",  2, { {0,  4, TRUE }, {5, 44, TRUE }},
-                              2, { {0,  4, TRUE }, {5, 44, TRUE }}},
-      {"/A: 1-44*", "/A: 5",  1, { {0, 44, FALSE} },
-                              2, { {0,  4, FALSE}, {5, 44, FALSE}}},
-      {"/A: 1-44",  "/A: 5*", 1, { {0, 44, TRUE } },
-                              2, { {0,  4, TRUE }, {5, 44, TRUE }}},
-      {"/A: 1-44*", "/A: 5*", 2, { {0,  4, FALSE}, {5, 44, FALSE}},
-                              2, { {0,  4, FALSE}, {5, 44, FALSE}}},
+      {"1-44",  "5",  2, { {0,  4, TRUE }, {5, 44, TRUE }},
+                      2, { {0,  4, TRUE }, {5, 44, TRUE }}},
+      {"1-44*", "5",  1, { {0, 44, FALSE} },
+                      2, { {0,  4, FALSE}, {5, 44, FALSE}}},
+      {"1-44",  "5*", 1, { {0, 44, TRUE } },
+                      2, { {0,  4, TRUE }, {5, 44, TRUE }}},
+      {"1-44*", "5*", 2, { {0,  4, FALSE}, {5, 44, FALSE}},
+                      2, { {0,  4, FALSE}, {5, 44, FALSE}}},
       /* Non-intersecting ranges...nothing is removed */
-      {"/A: 2-9,14-19",   "/A: 12",  2, { {1, 9, TRUE }, {13, 19, TRUE }},
-                                     2, { {1, 9, TRUE }, {13, 19, TRUE }}},
-      {"/A: 2-9*,14-19*", "/A: 12",  2, { {1, 9, FALSE}, {13, 19, FALSE}},
-                                     2, { {1, 9, FALSE}, {13, 19, FALSE}}},
-      {"/A: 2-9,14-19",   "/A: 12*", 2, { {1, 9, TRUE }, {13, 19, TRUE }},
-                                     2, { {1, 9, TRUE }, {13, 19, TRUE }}},
-      {"/A: 2-9*,14-19*", "/A: 12*", 2, { {1, 9, FALSE}, {13, 19, FALSE}},
-                                     2, { {1, 9, FALSE}, {13, 19, FALSE}}},
+      {"2-9,14-19",   "12",  2, { {1, 9, TRUE }, {13, 19, TRUE }},
+                             2, { {1, 9, TRUE }, {13, 19, TRUE }}},
+      {"2-9*,14-19*", "12",  2, { {1, 9, FALSE}, {13, 19, FALSE}},
+                             2, { {1, 9, FALSE}, {13, 19, FALSE}}},
+      {"2-9,14-19",   "12*", 2, { {1, 9, TRUE }, {13, 19, TRUE }},
+                             2, { {1, 9, TRUE }, {13, 19, TRUE }}},
+      {"2-9*,14-19*", "12*", 2, { {1, 9, FALSE}, {13, 19, FALSE}},
+                             2, { {1, 9, FALSE}, {13, 19, FALSE}}},
       /* Eraser overlaps whiteboard */
-      {"/A: 1,9-17",  "/A: 12-20",  2, { {0,  1, TRUE }, {8, 11, TRUE }},
-                                    2, { {0,  1, TRUE }, {8, 11, TRUE }}},
-      {"/A: 1,9-17*", "/A: 12-20",  2, { {0,  1, TRUE }, {8, 17, FALSE}},
-                                    2, { {0,  1, TRUE }, {8, 11, FALSE}}},
-      {"/A: 1,9-17",  "/A: 12-20*", 2, { {0,  1, TRUE }, {8, 17, TRUE }},
-                                    2, { {0,  1, TRUE }, {8, 11, TRUE }}},
-      {"/A: 1,9-17*", "/A: 12-20*", 2, { {0,  1, TRUE }, {8, 11, FALSE}},
-                                    2, { {0,  1, TRUE }, {8, 11, FALSE}}},
-      /* Empty mergeinfo (i.e. empty rangelist) */
-      {"",  "",               0, { {0, 0, FALSE}},
-                              0, { {0, 0, FALSE}}},
-      {"",  "/A: 5-8,10-100", 0, { {0, 0, FALSE}},
-                              0, { {0, 0, FALSE}}},
-      {"/A: 5-8,10-100",  "", 2, { {4, 8, TRUE }, {9, 100, TRUE }},
-                              2, { {4, 8, TRUE }, {9, 100, TRUE }}}
+      {"1,9-17",  "12-20",  2, { {0,  1, TRUE }, {8, 11, TRUE }},
+                            2, { {0,  1, TRUE }, {8, 11, TRUE }}},
+      {"1,9-17*", "12-20",  2, { {0,  1, TRUE }, {8, 17, FALSE}},
+                            2, { {0,  1, TRUE }, {8, 11, FALSE}}},
+      {"1,9-17",  "12-20*", 2, { {0,  1, TRUE }, {8, 17, TRUE }},
+                            2, { {0,  1, TRUE }, {8, 11, TRUE }}},
+      {"1,9-17*", "12-20*", 2, { {0,  1, TRUE }, {8, 11, FALSE}},
+                            2, { {0,  1, TRUE }, {8, 11, FALSE}}},
+      /* Empty rangelist */
+      {"",  "",           0, { {0, 0, FALSE}},
+                          0, { {0, 0, FALSE}}},
+      {"",  "5-8,10-100", 0, { {0, 0, FALSE}},
+                          0, { {0, 0, FALSE}}},
+      {"5-8,10-100",  "", 2, { {4, 8, TRUE }, {9, 100, TRUE }},
+                          2, { {4, 8, TRUE }, {9, 100, TRUE }}}
     };
 
   err = child_err = SVN_NO_ERROR;
@@ -847,10 +827,8 @@ test_remove_rangelist(apr_pool_t *pool)
           svn_string_t *whiteboard_starting;
           svn_string_t *whiteboard_ending;
 
-          SVN_ERR(svn_mergeinfo_parse(&info1, (test_data[i]).eraser, pool));
-          SVN_ERR(svn_mergeinfo_parse(&info2, (test_data[i]).whiteboard, pool));
-          eraser = apr_hash_get(info1, "/A", APR_HASH_KEY_STRING);
-          whiteboard = apr_hash_get(info2, "/A", APR_HASH_KEY_STRING);
+          SVN_ERR(svn_rangelist__parse(&eraser, test_data[i].eraser, pool));
+          SVN_ERR(svn_rangelist__parse(&whiteboard, test_data[i].whiteboard, pool));
 
           /* Represent empty mergeinfo with an empty rangelist. */
           if (eraser == NULL)
@@ -1201,118 +1179,118 @@ test_rangelist_merge(apr_pool_t *pool)
   struct rangelist_merge_test_data test_data[SIZE_OF_RANGE_MERGE_TEST_ARRAY] =
     {
       /* Non-intersecting ranges */
-      {"/A: 1-44",    "/A: 70-101",  2, {{ 0, 44, TRUE }, {69, 101, TRUE }}},
-      {"/A: 1-44*",   "/A: 70-101",  2, {{ 0, 44, FALSE}, {69, 101, TRUE }}},
-      {"/A: 1-44",    "/A: 70-101*", 2, {{ 0, 44, TRUE }, {69, 101, FALSE}}},
-      {"/A: 1-44*",   "/A: 70-101*", 2, {{ 0, 44, FALSE}, {69, 101, FALSE}}},
-      {"/A: 70-101",  "/A: 1-44",    2, {{ 0, 44, TRUE }, {69, 101, TRUE }}},
-      {"/A: 70-101*", "/A: 1-44",    2, {{ 0, 44, TRUE }, {69, 101, FALSE}}},
-      {"/A: 70-101",  "/A: 1-44*",   2, {{ 0, 44, FALSE}, {69, 101, TRUE }}},
-      {"/A: 70-101*", "/A: 1-44*",   2, {{ 0, 44, FALSE}, {69, 101, FALSE}}},
+      {"1-44",    "70-101",  2, {{ 0, 44, TRUE }, {69, 101, TRUE }}},
+      {"1-44*",   "70-101",  2, {{ 0, 44, FALSE}, {69, 101, TRUE }}},
+      {"1-44",    "70-101*", 2, {{ 0, 44, TRUE }, {69, 101, FALSE}}},
+      {"1-44*",   "70-101*", 2, {{ 0, 44, FALSE}, {69, 101, FALSE}}},
+      {"70-101",  "1-44",    2, {{ 0, 44, TRUE }, {69, 101, TRUE }}},
+      {"70-101*", "1-44",    2, {{ 0, 44, TRUE }, {69, 101, FALSE}}},
+      {"70-101",  "1-44*",   2, {{ 0, 44, FALSE}, {69, 101, TRUE }}},
+      {"70-101*", "1-44*",   2, {{ 0, 44, FALSE}, {69, 101, FALSE}}},
 
       /* Intersecting ranges with same starting and ending revisions */
-      {"/A: 4-20",  "/A: 4-20",  1, {{3, 20, TRUE }}},
-      {"/A: 4-20*", "/A: 4-20",  1, {{3, 20, TRUE }}},
-      {"/A: 4-20",  "/A: 4-20*", 1, {{3, 20, TRUE }}},
-      {"/A: 4-20*", "/A: 4-20*", 1, {{3, 20, FALSE}}},
+      {"4-20",  "4-20",  1, {{3, 20, TRUE }}},
+      {"4-20*", "4-20",  1, {{3, 20, TRUE }}},
+      {"4-20",  "4-20*", 1, {{3, 20, TRUE }}},
+      {"4-20*", "4-20*", 1, {{3, 20, FALSE}}},
 
       /* Intersecting ranges with same starting revision */
-      {"/A: 6-17",  "/A: 6-12",  1, {{5, 17, TRUE}}},
-      {"/A: 6-17*", "/A: 6-12",  2, {{5, 12, TRUE }, {12, 17, FALSE}}},
-      {"/A: 6-17",  "/A: 6-12*", 1, {{5, 17, TRUE }}},
-      {"/A: 6-17*", "/A: 6-12*", 1, {{5, 17, FALSE}}},
-      {"/A: 6-12",  "/A: 6-17",  1, {{5, 17, TRUE }}},
-      {"/A: 6-12*", "/A: 6-17",  1, {{5, 17, TRUE }}},
-      {"/A: 6-12",  "/A: 6-17*", 2, {{5, 12, TRUE }, {12, 17, FALSE}}},
-      {"/A: 6-12*", "/A: 6-17*", 1, {{5, 17, FALSE}}},
+      {"6-17",  "6-12",  1, {{5, 17, TRUE}}},
+      {"6-17*", "6-12",  2, {{5, 12, TRUE }, {12, 17, FALSE}}},
+      {"6-17",  "6-12*", 1, {{5, 17, TRUE }}},
+      {"6-17*", "6-12*", 1, {{5, 17, FALSE}}},
+      {"6-12",  "6-17",  1, {{5, 17, TRUE }}},
+      {"6-12*", "6-17",  1, {{5, 17, TRUE }}},
+      {"6-12",  "6-17*", 2, {{5, 12, TRUE }, {12, 17, FALSE}}},
+      {"6-12*", "6-17*", 1, {{5, 17, FALSE}}},
 
       /* Intersecting ranges with same ending revision */
-      {"/A: 5-77",   "/A: 44-77",  1, {{4, 77, TRUE }}},
-      {"/A: 5-77*",  "/A: 44-77",  2, {{4, 43, FALSE}, {43, 77, TRUE}}},
-      {"/A: 5-77",   "/A: 44-77*", 1, {{4, 77, TRUE }}},
-      {"/A: 5-77*",  "/A: 44-77*", 1, {{4, 77, FALSE}}},
-      {"/A: 44-77",  "/A: 5-77",   1, {{4, 77, TRUE }}},
-      {"/A: 44-77*", "/A: 5-77",   1, {{4, 77, TRUE }}},
-      {"/A: 44-77",  "/A: 5-77*",  2, {{4, 43, FALSE}, {43, 77, TRUE}}},
-      {"/A: 44-77*", "/A: 5-77*",  1, {{4, 77, FALSE}}},
+      {"5-77",   "44-77",  1, {{4, 77, TRUE }}},
+      {"5-77*",  "44-77",  2, {{4, 43, FALSE}, {43, 77, TRUE}}},
+      {"5-77",   "44-77*", 1, {{4, 77, TRUE }}},
+      {"5-77*",  "44-77*", 1, {{4, 77, FALSE}}},
+      {"44-77",  "5-77",   1, {{4, 77, TRUE }}},
+      {"44-77*", "5-77",   1, {{4, 77, TRUE }}},
+      {"44-77",  "5-77*",  2, {{4, 43, FALSE}, {43, 77, TRUE}}},
+      {"44-77*", "5-77*",  1, {{4, 77, FALSE}}},
 
       /* Intersecting ranges with different starting and ending revision
          where one range is a proper subset of the other. */
-      {"/A: 12-24",  "/A: 20-23",  1, {{11, 24, TRUE }}},
-      {"/A: 12-24*", "/A: 20-23",  3, {{11, 19, FALSE}, {19, 23, TRUE },
-                                       {23, 24, FALSE}}},
-      {"/A: 12-24",  "/A: 20-23*", 1, {{11, 24, TRUE }}},
-      {"/A: 12-24*", "/A: 20-23*", 1, {{11, 24, FALSE}}},
-      {"/A: 20-23",  "/A: 12-24",  1, {{11, 24, TRUE }}},
-      {"/A: 20-23*", "/A: 12-24",  1, {{11, 24, TRUE }}},
-      {"/A: 20-23",  "/A: 12-24*", 3, {{11, 19, FALSE}, {19, 23, TRUE },
-                                       {23, 24, FALSE}}},
-      {"/A: 20-23*", "/A: 12-24*", 1, {{11, 24, FALSE}}},
+      {"12-24",  "20-23",  1, {{11, 24, TRUE }}},
+      {"12-24*", "20-23",  3, {{11, 19, FALSE}, {19, 23, TRUE },
+                               {23, 24, FALSE}}},
+      {"12-24",  "20-23*", 1, {{11, 24, TRUE }}},
+      {"12-24*", "20-23*", 1, {{11, 24, FALSE}}},
+      {"20-23",  "12-24",  1, {{11, 24, TRUE }}},
+      {"20-23*", "12-24",  1, {{11, 24, TRUE }}},
+      {"20-23",  "12-24*", 3, {{11, 19, FALSE}, {19, 23, TRUE },
+                               {23, 24, FALSE}}},
+      {"20-23*", "12-24*", 1, {{11, 24, FALSE}}},
 
       /* Intersecting ranges with different starting and ending revision
          where neither range is a proper subset of the other. */
-      {"/A: 50-73",  "/A: 60-99",  1, {{49, 99, TRUE }}},
-      {"/A: 50-73*", "/A: 60-99",  2, {{49, 59, FALSE}, {59, 99, TRUE }}},
-      {"/A: 50-73",  "/A: 60-99*", 2, {{49, 73, TRUE }, {73, 99, FALSE}}},
-      {"/A: 50-73*", "/A: 60-99*", 1, {{49, 99, FALSE}}},
-      {"/A: 60-99",  "/A: 50-73",  1, {{49, 99, TRUE }}},
-      {"/A: 60-99*", "/A: 50-73",  2, {{49, 73, TRUE }, {73, 99, FALSE}}},
-      {"/A: 60-99",  "/A: 50-73*", 2, {{49, 59, FALSE}, {59, 99, TRUE }}},
-      {"/A: 60-99*", "/A: 50-73*", 1, {{49, 99, FALSE}}},
+      {"50-73",  "60-99",  1, {{49, 99, TRUE }}},
+      {"50-73*", "60-99",  2, {{49, 59, FALSE}, {59, 99, TRUE }}},
+      {"50-73",  "60-99*", 2, {{49, 73, TRUE }, {73, 99, FALSE}}},
+      {"50-73*", "60-99*", 1, {{49, 99, FALSE}}},
+      {"60-99",  "50-73",  1, {{49, 99, TRUE }}},
+      {"60-99*", "50-73",  2, {{49, 73, TRUE }, {73, 99, FALSE}}},
+      {"60-99",  "50-73*", 2, {{49, 59, FALSE}, {59, 99, TRUE }}},
+      {"60-99*", "50-73*", 1, {{49, 99, FALSE}}},
 
       /* Multiple ranges. */
-      {"/A: 1-5,7,12-13",    "/A: 2-17",  1, {{0,  17, TRUE }}},
-      {"/A: 1-5*,7*,12-13*", "/A: 2-17*", 1, {{0,  17, FALSE}}},
+      {"1-5,7,12-13",    "2-17",  1, {{0,  17, TRUE }}},
+      {"1-5*,7*,12-13*", "2-17*", 1, {{0,  17, FALSE}}},
 
-      {"/A: 1-5,7,12-13",    "/A: 2-17*", 6,
+      {"1-5,7,12-13",    "2-17*", 6,
        {{0,  5, TRUE }, { 5,  6, FALSE}, { 6,  7, TRUE },
         {7, 11, FALSE}, {11, 13, TRUE }, {13, 17, FALSE}}},
 
-      {"/A: 1-5*,7*,12-13*", "/A: 2-17", 2,
+      {"1-5*,7*,12-13*", "2-17", 2,
        {{0, 1, FALSE}, {1, 17, TRUE }}},
 
-      {"/A: 2-17",  "/A: 1-5,7,12-13",    1, {{0,  17, TRUE }}},
-      {"/A: 2-17*", "/A: 1-5*,7*,12-13*", 1, {{0,  17, FALSE}}},
+      {"2-17",  "1-5,7,12-13",    1, {{0,  17, TRUE }}},
+      {"2-17*", "1-5*,7*,12-13*", 1, {{0,  17, FALSE}}},
 
-      {"/A: 2-17*", "/A: 1-5,7,12-13", 6,
+      {"2-17*", "1-5,7,12-13", 6,
        {{0,  5, TRUE }, { 5,  6, FALSE}, { 6,  7, TRUE },
         {7, 11, FALSE}, {11, 13, TRUE }, {13, 17, FALSE}}},
 
-      {"/A: 2-17", "/A: 1-5*,7*,12-13*", 2,
+      {"2-17", "1-5*,7*,12-13*", 2,
        {{0, 1, FALSE}, {1, 17, TRUE}}},
 
-      {"/A: 3-4*,10-15,20", "/A: 5-60*", 5,
+      {"3-4*,10-15,20", "5-60*", 5,
        {{2, 9, FALSE}, {9, 15, TRUE}, {15, 19, FALSE},{19, 20, TRUE},
         {20, 60, FALSE}}},
 
-      {"/A: 5-60*", "/A: 3-4*,10-15,20", 5,
+      {"5-60*", "3-4*,10-15,20", 5,
        {{2, 9, FALSE}, {9, 15, TRUE}, {15, 19, FALSE},{19, 20, TRUE},
         {20, 60, FALSE}}},
 
-      {"/A: 3-4*,50-100*", "/A: 5-60*", 1, {{2, 100, FALSE}}},
+      {"3-4*,50-100*", "5-60*", 1, {{2, 100, FALSE}}},
 
-      {"/A: 5-60*", "/A: 3-4*,50-100*", 1, {{2, 100, FALSE}}},
+      {"5-60*", "3-4*,50-100*", 1, {{2, 100, FALSE}}},
 
-      {"/A: 3-4*,50-100", "/A: 5-60*", 2, {{2, 49, FALSE}, {49, 100, TRUE}}},
+      {"3-4*,50-100", "5-60*", 2, {{2, 49, FALSE}, {49, 100, TRUE}}},
 
-      {"/A: 5-60*", "/A: 3-4*,50-100", 2, {{2, 49, FALSE}, {49, 100, TRUE}}},
+      {"5-60*", "3-4*,50-100", 2, {{2, 49, FALSE}, {49, 100, TRUE}}},
 
-      {"/A: 3-4,50-100*", "/A: 5-60", 2, {{2, 60, TRUE}, {60, 100, FALSE}}},
+      {"3-4,50-100*", "5-60", 2, {{2, 60, TRUE}, {60, 100, FALSE}}},
 
-      {"/A: 5-60", "/A: 3-4,50-100*", 2, {{2, 60, TRUE}, {60, 100, FALSE}}},
+      {"5-60", "3-4,50-100*", 2, {{2, 60, TRUE}, {60, 100, FALSE}}},
 
-      {"/A: 5,9,11-15,17,200-300,999", "/A: 7-50", 4,
+      {"5,9,11-15,17,200-300,999", "7-50", 4,
        {{4, 5, TRUE}, {6, 50, TRUE}, {199, 300, TRUE}, {998, 999, TRUE}}},
 
       /* A rangelist merged with an empty rangelist should equal the
          non-empty rangelist but in compacted form. */
-      {"/A: 1-44,45,46,47-50",       "",  1, {{ 0, 50, TRUE }}},
-      {"/A: 1,2,3,4,5,6,7,8",        "",  1, {{ 0, 8,  TRUE }}},
-      {"/A: 6-10,12-13,14,15,16-22", "",  2,
+      {"1-44,45,46,47-50",       "",  1, {{ 0, 50, TRUE }}},
+      {"1,2,3,4,5,6,7,8",        "",  1, {{ 0, 8,  TRUE }}},
+      {"6-10,12-13,14,15,16-22", "",  2,
        {{ 5, 10, TRUE }, { 11, 22, TRUE }}},
-      {"", "/A: 1-44,45,46,47-50",        1, {{ 0, 50, TRUE }}},
-      {"", "/A: 1,2,3,4,5,6,7,8",         1, {{ 0, 8,  TRUE }}},
-      {"", "/A: 6-10,12-13,14,15,16-22",  2,
+      {"", "1-44,45,46,47-50",        1, {{ 0, 50, TRUE }}},
+      {"", "1,2,3,4,5,6,7,8",         1, {{ 0, 8,  TRUE }}},
+      {"", "6-10,12-13,14,15,16-22",  2,
        {{ 5, 10, TRUE }, { 11, 22, TRUE }}},
 
       /* An empty rangelist merged with an empty rangelist is, drum-roll
@@ -1325,10 +1303,8 @@ test_rangelist_merge(apr_pool_t *pool)
     {
       svn_string_t *rangelist2_starting, *rangelist2_ending;
 
-      SVN_ERR(svn_mergeinfo_parse(&info1, (test_data[i]).mergeinfo1, pool));
-      SVN_ERR(svn_mergeinfo_parse(&info2, (test_data[i]).mergeinfo2, pool));
-      rangelist1 = apr_hash_get(info1, "/A", APR_HASH_KEY_STRING);
-      rangelist2 = apr_hash_get(info2, "/A", APR_HASH_KEY_STRING);
+      SVN_ERR(svn_rangelist__parse(&rangelist1, test_data[i].mergeinfo1, pool));
+      SVN_ERR(svn_rangelist__parse(&rangelist2, test_data[i].mergeinfo2, pool));
 
       /* Create empty rangelists if necessary. */
       if (rangelist1 == NULL)
@@ -1412,7 +1388,7 @@ test_rangelist_diff(apr_pool_t *pool)
   #define SIZE_OF_RANGE_DIFF_TEST_ARRAY 16
   /* The actual test data array.
 
-                    'from' --> {"/A: 1,5-8",  "/A: 1,6,10-12", <-- 'to'
+                    'from' --> {"1,5-8",  "1,6,10-12", <-- 'to'
       Number of adds when  -->  1, { { 9, 12, TRUE } },
       considering inheritance
 
@@ -1430,97 +1406,97 @@ test_rangelist_diff(apr_pool_t *pool)
   struct rangelist_diff_test_data test_data[SIZE_OF_RANGE_DIFF_TEST_ARRAY] =
     {
       /* Add and Delete */
-      {"/A: 1",  "/A: 3",
+      {"1",  "3",
        1, { { 2, 3, TRUE } },
        1, { { 0, 1, TRUE } },
        1, { { 2, 3, TRUE } },
        1, { { 0, 1, TRUE } } },
 
       /* Add only */
-      {"/A: 1",  "/A: 1,3",
+      {"1",  "1,3",
        1, { { 2, 3, TRUE } },
        0, { { 0, 0, FALSE } },
        1, { { 2, 3, TRUE } },
        0, { { 0, 0, FALSE } } },
 
       /* Delete only */
-      {"/A: 1,3",  "/A: 1",
+      {"1,3",  "1",
        0, { { 0, 0, FALSE } },
        1, { { 2, 3, TRUE  } },
        0, { { 0, 0, FALSE } },
        1, { { 2, 3, TRUE  } } },
 
       /* No diff */
-      {"/A: 1,3",  "/A: 1,3",
+      {"1,3",  "1,3",
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } } },
 
-      {"/A: 1,3*",  "/A: 1,3*",
+      {"1,3*",  "1,3*",
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } } },
 
       /* Adds and Deletes */
-      {"/A: 1,5-8",  "/A: 1,6,10-12",
+      {"1,5-8",  "1,6,10-12",
        1, { { 9, 12, TRUE } },
        2, { { 4, 5, TRUE }, { 6, 8, TRUE } },
        1, { { 9, 12, TRUE } },
        2, { { 4, 5, TRUE }, { 6, 8, TRUE } } },
 
-      {"/A: 6*",  "/A: 6",
+      {"6*",  "6",
        1, { { 5, 6, TRUE  } },
        1, { { 5, 6, FALSE } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } } },
 
       /* Intersecting range with different inheritability */
-      {"/A: 6",  "/A: 6*",
+      {"6",  "6*",
        1, { { 5, 6, FALSE } },
        1, { { 5, 6, TRUE  } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } } },
 
-      {"/A: 6*",  "/A: 6",
+      {"6*",  "6",
        1, { { 5, 6, TRUE  } },
        1, { { 5, 6, FALSE } },
        0, { { 0, 0, FALSE } },
        0, { { 0, 0, FALSE } } },
 
-      {"/A: 1,5-8",  "/A: 1,6*,10-12",
+      {"1,5-8",  "1,6*,10-12",
        2, { { 5,  6, FALSE }, { 9, 12, TRUE } },
        1, { { 4,  8, TRUE  } },
        1, { { 9, 12, TRUE  } },
        2, { { 4,  5, TRUE  }, { 6,  8, TRUE } } },
 
-     {"/A: 1,5-8*",  "/A: 1,6,10-12",
+     {"1,5-8*",  "1,6,10-12",
        2, { { 5,  6, TRUE  }, { 9, 12, TRUE  } },
        1, { { 4,  8, FALSE } },
        1, { { 9, 12, TRUE  } },
        2, { { 4,  5, FALSE }, { 6,  8, FALSE } } },
 
       /* Empty range diffs */
-      {"/A: 3-9",  "",
+      {"3-9",  "",
        0, { { 0, 0, FALSE } },
        1, { { 2, 9, TRUE  } },
        0, { { 0, 0, FALSE } },
        1, { { 2, 9, TRUE  } } },
 
-      {"/A: 3-9*",  "",
+      {"3-9*",  "",
        0, { { 0, 0, FALSE } },
        1, { { 2, 9, FALSE } },
        0, { { 0, 0, FALSE } },
        1, { { 2, 9, FALSE } } },
 
-      {"",  "/A: 3-9",
+      {"",  "3-9",
        1, { { 2, 9, TRUE  } },
        0, { { 0, 0, FALSE } },
        1, { { 2, 9, TRUE  } },
        0, { { 0, 0, FALSE } } },
 
-      {"",  "/A: 3-9*",
+      {"",  "3-9*",
        1, { { 2, 9, FALSE } },
        0, { { 0, 0, FALSE } },
        1, { { 2, 9, FALSE } },
@@ -1537,10 +1513,8 @@ test_rangelist_diff(apr_pool_t *pool)
   err = child_err = SVN_NO_ERROR;
   for (i = 0; i < SIZE_OF_RANGE_DIFF_TEST_ARRAY; i++)
     {
-      SVN_ERR(svn_mergeinfo_parse(&info1, (test_data[i]).to, pool));
-      SVN_ERR(svn_mergeinfo_parse(&info2, (test_data[i]).from, pool));
-      to = apr_hash_get(info1, "/A", APR_HASH_KEY_STRING);
-      from = apr_hash_get(info2, "/A", APR_HASH_KEY_STRING);
+      SVN_ERR(svn_rangelist__parse(&to, test_data[i].to, pool));
+      SVN_ERR(svn_rangelist__parse(&from, test_data[i].from, pool));
 
       /* Represent empty mergeinfo with an empty rangelist. */
       if (to == NULL)
@@ -1721,14 +1695,14 @@ struct svn_test_descriptor_t test_funcs[
     SVN_TEST_PASS2(test_diff_mergeinfo,
                    "diff of mergeinfo"),
     SVN_TEST_PASS2(test_merge_mergeinfo,
-                   "merging of mergeinfo hashs"),
+                   "merging of mergeinfo hashes"),
     SVN_TEST_PASS2(test_mergeinfo_intersect,
                    "intersection of mergeinfo"),
     SVN_TEST_PASS2(test_rangelist_to_string,
                    "turning rangelist back into a string"),
     SVN_TEST_PASS2(test_mergeinfo_to_string,
                    "turning mergeinfo back into a string"),
-    SVN_TEST_PASS2(test_rangelist_merge,
+    SVN_TEST_XFAIL2(test_rangelist_merge,
                    "merge of rangelists"),
     SVN_TEST_PASS2(test_rangelist_diff,
                    "diff of rangelists"),

Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/path-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/path-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/path-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/path-test.c Mon Dec 19 18:49:34 2011
@@ -871,7 +871,7 @@ test_path_remove_component(apr_pool_t *p
   int i;
   svn_stringbuf_t *buf;
 
-  buf = svn_stringbuf_create("", pool);
+  buf = svn_stringbuf_create_empty(pool);
 
   i = 0;
   while (tests[i].path)

Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/stream-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/stream-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/stream-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/stream-test.c Mon Dec 19 18:49:34 2011
@@ -67,7 +67,7 @@ test_stream_from_string(apr_pool_t *pool
       apr_size_t len;
 
       inbuf = svn_stringbuf_create(strings[i], subpool);
-      outbuf = svn_stringbuf_create("", subpool);
+      outbuf = svn_stringbuf_create_empty(subpool);
       stream = svn_stream_from_stringbuf(inbuf, subpool);
       len = TEST_BUF_SIZE;
       while (len == TEST_BUF_SIZE)
@@ -94,7 +94,7 @@ test_stream_from_string(apr_pool_t *pool
       apr_size_t amt_read, len;
 
       inbuf = svn_stringbuf_create(strings[i], subpool);
-      outbuf = svn_stringbuf_create("", subpool);
+      outbuf = svn_stringbuf_create_empty(subpool);
       stream = svn_stream_from_stringbuf(outbuf, subpool);
       amt_read = 0;
       while (amt_read < inbuf->len)
@@ -125,7 +125,7 @@ test_stream_from_string(apr_pool_t *pool
 static svn_stringbuf_t *
 generate_test_bytes(int num_bytes, apr_pool_t *pool)
 {
-  svn_stringbuf_t *buffer = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *buffer = svn_stringbuf_create_empty(pool);
   int total, repeat, repeat_iter;
   char c;
 
@@ -189,8 +189,8 @@ test_stream_compressed(apr_pool_t *pool)
       apr_size_t len;
 
       origbuf = bufs[i];
-      inbuf = svn_stringbuf_create("", subpool);
-      outbuf = svn_stringbuf_create("", subpool);
+      inbuf = svn_stringbuf_create_empty(subpool);
+      outbuf = svn_stringbuf_create_empty(subpool);
 
       stream = svn_stream_compressed(svn_stream_from_stringbuf(outbuf,
                                                                subpool),
@@ -232,8 +232,8 @@ static svn_error_t *
 test_stream_tee(apr_pool_t *pool)
 {
   svn_stringbuf_t *test_bytes = generate_test_bytes(100, pool);
-  svn_stringbuf_t *output_buf1 = svn_stringbuf_create("", pool);
-  svn_stringbuf_t *output_buf2 = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *output_buf1 = svn_stringbuf_create_empty(pool);
+  svn_stringbuf_t *output_buf2 = svn_stringbuf_create_empty(pool);
   svn_stream_t *source_stream = svn_stream_from_stringbuf(test_bytes, pool);
   svn_stream_t *output_stream1 = svn_stream_from_stringbuf(output_buf1, pool);
   svn_stream_t *output_stream2 = svn_stream_from_stringbuf(output_buf2, pool);
@@ -538,8 +538,8 @@ static svn_error_t *
 test_stream_base64(apr_pool_t *pool)
 {
   svn_stream_t *stream;
-  svn_stringbuf_t *actual = svn_stringbuf_create("", pool);
-  svn_stringbuf_t *expected = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *actual = svn_stringbuf_create_empty(pool);
+  svn_stringbuf_t *expected = svn_stringbuf_create_empty(pool);
   int i;
   static const char *strings[] = {
     "fairly boring test data... blah blah",

Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/string-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/string-test.c Mon Dec 19 18:49:34 2011
@@ -419,7 +419,7 @@ test15(apr_pool_t *pool)
 static svn_error_t *
 test16(apr_pool_t *pool)
 {
-  a = svn_stringbuf_create("", pool);
+  a = svn_stringbuf_create_empty(pool);
 
   return test_find_char_backward(a->data, a->len, ',', 0, pool);
 }

Modified: subversion/branches/fs-py/subversion/tests/libsvn_subr/subst_translate-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_subr/subst_translate-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_subr/subst_translate-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_subr/subst_translate-test.c Mon Dec 19 18:49:34 2011
@@ -115,7 +115,7 @@ test_svn_subst_translate_string2_null_en
     svn_string_t *new_value = NULL;
     svn_boolean_t translated_to_utf8 = FALSE;
     svn_boolean_t translated_line_endings = TRUE;
-    /* 'Æ', which is 0xc6 in both ISO-8859-1 and Windows-1252 */
+    /* 'Æ', which is 0xc6 in both ISO-8859-1 and Windows-1252 */
     svn_string_t *source_string = svn_string_create("\xc6", pool);
 
     SVN_ERR(svn_subst_translate_string2(&new_value, &translated_to_utf8,

Propchange: subversion/branches/fs-py/subversion/tests/libsvn_wc/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Dec 19 18:49:34 2011
@@ -8,3 +8,4 @@ svn-test-work
 entries-compat-test
 op-depth-test
 wc-lock-tester
+wc-incomplete-tester

Modified: subversion/branches/fs-py/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_wc/db-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_wc/db-test.c Mon Dec 19 18:49:34 2011
@@ -1053,7 +1053,7 @@ test_scan_deletion(apr_pool_t *pool)
             &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-e", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
                                    moved_to_abspath, pool));
@@ -1070,7 +1070,7 @@ test_scan_deletion(apr_pool_t *pool)
             &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-e/J-e-a", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-a",
                                    moved_to_abspath, pool));
@@ -1120,7 +1120,7 @@ test_scan_deletion(apr_pool_t *pool)
   /* ### I don't understand this.  "J/J-e/J-e-b/Jeba" is a deleted
      base node that is not overlayed by the replacement rooted at "J".
      Why does base_del_abspath refer to "J-e"?  */
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-b/Jeba",
                                    moved_to_abspath, pool));
@@ -1174,7 +1174,7 @@ test_scan_deletion(apr_pool_t *pool)
             &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "K/K-b", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "K/K-b",
+  SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
                                    moved_to_abspath, pool));

Modified: subversion/branches/fs-py/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/libsvn_wc/op-depth-test.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/fs-py/subversion/tests/libsvn_wc/op-depth-test.c Mon Dec 19 18:49:34 2011
@@ -77,7 +77,7 @@ open_wc_db(svn_sqlite__db_t **sdb,
            apr_pool_t *scratch_pool)
 {
   SVN_ERR(svn_wc__db_util_open_db(sdb, wc_root_abspath, "wc.db",
-                                  svn_sqlite__mode_readonly, my_statements,
+                                  svn_sqlite__mode_readwrite, my_statements,
                                   result_pool, scratch_pool));
   return SVN_NO_ERROR;
 }
@@ -322,35 +322,50 @@ typedef struct nodes_row_t {
     svn_revnum_t repo_revnum;
     const char *repo_relpath;
     svn_boolean_t file_external;
+    const char *moved_to;
+    svn_boolean_t moved_here;
 } nodes_row_t;
 
 /* Macro for filling in the REPO_* fields of a non-base NODES_ROW_T
  * that has no copy-from info. */
 #define NO_COPY_FROM SVN_INVALID_REVNUM, NULL
+#define MOVED_HERE FALSE, NULL, TRUE
 
 /* Return a human-readable string representing ROW. */
 static const char *
 print_row(const nodes_row_t *row,
           apr_pool_t *result_pool)
 {
-  const char *file_external_str;
+  const char *file_external_str, *moved_here_str, *moved_to_str;
 
   if (row == NULL)
     return "(null)";
 
+  if (row->moved_to)
+    moved_to_str = apr_psprintf(result_pool, ", to %s", row->moved_to);
+  else
+    moved_to_str = "";
+
+  if (row->moved_here)
+    moved_here_str = ", here";
+  else
+    moved_here_str = "";
+      
   if (row->file_external)
     file_external_str = ", file-external";
   else
     file_external_str = "";
       
   if (row->repo_revnum == SVN_INVALID_REVNUM)
-    return apr_psprintf(result_pool, "%d, %s, %s%s",
+    return apr_psprintf(result_pool, "%d, %s, %s%s%s%s",
                         row->op_depth, row->local_relpath, row->presence,
+                        moved_here_str, moved_to_str,
                         file_external_str);
   else
-    return apr_psprintf(result_pool, "%d, %s, %s, from ^/%s@%d%s",
+    return apr_psprintf(result_pool, "%d, %s, %s, from ^/%s@%d%s%s%s",
                         row->op_depth, row->local_relpath, row->presence,
                         row->repo_relpath, (int)row->repo_revnum,
+                        moved_here_str, moved_to_str,
                         file_external_str);
 }
 
@@ -393,7 +408,12 @@ compare_nodes_rows(const void *key, apr_
   else if (expected->repo_revnum != found->repo_revnum
            || (strcmp_null(expected->repo_relpath, found->repo_relpath) != 0)
            || (strcmp_null(expected->presence, found->presence) != 0)
-           || (expected->file_external != found->file_external))
+           || (expected->file_external != found->file_external)
+           || (expected->moved_here != found->moved_here)
+           || (expected->moved_to && !found->moved_to)
+           || (!expected->moved_to && found->moved_to)
+           || (expected->moved_to
+               && strcmp(expected->moved_to, found->moved_to)))
     {
       b->errors = svn_error_createf(
                     SVN_ERR_TEST_FAILED, b->errors,
@@ -423,7 +443,7 @@ check_db_rows(svn_test__sandbox_t *b,
   svn_sqlite__stmt_t *stmt;
   static const char *const statements[] = {
     "SELECT op_depth, nodes.presence, nodes.local_relpath, revision,"
-    "       repos_path, file_external, def_local_relpath"
+    "       repos_path, file_external, def_local_relpath, moved_to, moved_here"
     " FROM nodes "
     " LEFT OUTER JOIN externals"
     "             ON nodes.local_relpath = externals.local_relpath"
@@ -460,6 +480,8 @@ check_db_rows(svn_test__sandbox_t *b,
         comparison_baton.errors
           = svn_error_createf(SVN_ERR_TEST_FAILED, comparison_baton.errors,
                               "incomplete {%s}", print_row(row, b->pool));
+      row->moved_to = svn_sqlite__column_text(stmt, 7, b->pool);
+      row->moved_here = svn_sqlite__column_boolean(stmt, 8);
 
       key = apr_psprintf(b->pool, "%d %s", row->op_depth, row->local_relpath);
       apr_hash_set(found_hash, key, APR_HASH_KEY_STRING, row);
@@ -481,6 +503,7 @@ check_db_rows(svn_test__sandbox_t *b,
   /* Compare EXPECTED_HASH with ACTUAL_HASH and return any errors. */
   SVN_ERR(svn_hash_diff(expected_hash, found_hash,
                         compare_nodes_rows, &comparison_baton, b->pool));
+  SVN_ERR(svn_sqlite__close(sdb));
   return comparison_baton.errors;
 }
 
@@ -1690,9 +1713,9 @@ test_wc_move(const svn_test_opts_t *opts
       { 0, "",           "normal",       1, "" },
       { 0, "A",          "normal",       1, "A" },
       { 0, "A/B",        "normal",       1, "A/B" },
-      { 0, "A/B/C",      "normal",       1, "A/B/C" },
+      { 0, "A/B/C",      "normal",       1, "A/B/C", FALSE, "A/B/C-move" },
       { 3, "A/B/C",      "base-deleted", NO_COPY_FROM },
-      { 3, "A/B/C-move", "normal",       1, "A/B/C" },
+      { 3, "A/B/C-move", "normal",       1, "A/B/C", MOVED_HERE },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "", rows));
@@ -1703,14 +1726,14 @@ test_wc_move(const svn_test_opts_t *opts
     nodes_row_t rows[] = {
       { 0, "",                "normal",       1, "" },
       { 0, "A",               "normal",       1, "A" },
-      { 0, "A/B",             "normal",       1, "A/B" },
-      { 0, "A/B/C",           "normal",       1, "A/B/C" },
+      { 0, "A/B",             "normal",       1, "A/B", FALSE, "A/B-move" },
+      { 0, "A/B/C",           "normal",       1, "A/B/C", FALSE, "A/B-move/C-move" },
       { 2, "A/B",             "base-deleted", NO_COPY_FROM },
       { 2, "A/B/C",           "base-deleted", NO_COPY_FROM },
-      { 2, "A/B-move",        "normal",       1, "A/B" },
-      { 2, "A/B-move/C",      "normal",       1, "A/B/C" },
+      { 2, "A/B-move",        "normal",       1, "A/B", MOVED_HERE },
+      { 2, "A/B-move/C",      "normal",       1, "A/B/C", MOVED_HERE },
       { 3, "A/B-move/C",      "base-deleted", NO_COPY_FROM },
-      { 3, "A/B-move/C-move", "normal",       1, "A/B/C" },
+      { 3, "A/B-move/C-move", "normal",       1, "A/B/C", MOVED_HERE },
       { 0 }
     };
     SVN_ERR(check_db_rows(&b, "", rows));
@@ -3145,7 +3168,9 @@ test_shadowed_update(const svn_test_opts
   SVN_ERR(wc_update(&b, "", 2));
   SVN_ERR(wc_copy(&b, "A", "A_tmp"));
   SVN_ERR(wc_update(&b, "", 1));
-  SVN_ERR(wc_move(&b, "A_tmp", "A"));
+  SVN_ERR(wc_move(&b, "A_tmp", "A")); /* ### XFAIL: sets moved-here on
+                                         A but A_tmp is removed and so
+                                         does not have moved-to. */
 
   SVN_ERR(wc_mkdir(&b, "K"));
   SVN_ERR(wc_mkdir(&b, "K/L"));
@@ -3669,6 +3694,780 @@ copy_wc_wc_absent(const svn_test_opts_t 
   return SVN_NO_ERROR;
 }
 
+/* Issue 4040 */
+static svn_error_t *
+incomplete_switch(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "incomplete_switch", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C/D"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_copy(&b, "A", "X"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_copy(&b, "A", "X/A"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_delete(&b, "X/A"));
+  SVN_ERR(wc_commit(&b, ""));
+
+  {
+    /* Interrupted switch from A@1 to X@3 */
+    nodes_row_t before[] = {
+      {0, "",      "incomplete", 3, "X"},
+      {0, "A",     "incomplete", 3, "X/A"},
+      {0, "A/B",   "incomplete", 3, "X/A/B"},
+      {0, "A/B/C", "incomplete", 3, "X/A/B/C"},
+      {0, "B",     "normal",     1, "A/B"},
+      {0, "B/C",   "normal",     1, "A/B/C"},
+      {0, "B/C/D", "normal",     1, "A/B/C/D"},
+      {0}
+    };
+
+    nodes_row_t after_update[] = { 
+      {0, "",      "normal", 4, "X"},
+      {0, "B",     "normal", 4, "A/B"},
+      {0, "B/C",   "normal", 4, "A/B/C"},
+      {0, "B/C/D", "normal", 4, "A/B/C/D"},
+      {0}
+    };
+
+    SVN_ERR(insert_dirs(&b, before));
+    SVN_ERR(check_db_rows(&b, "", before));
+    SVN_ERR(wc_update(&b, "", 4));
+    SVN_ERR(check_db_rows(&b, "", after_update));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_moves_child_first(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "nested_moves_child_first", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",      "normal", 1, ""},
+      {0, "A",     "normal", 1, "A"},
+      {0, "A/B",   "normal", 1, "A/B"},
+      {0, "A/B/C", "normal", 1, "A/B/C"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A/B/C", "A/B/C2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",       "normal",       1, ""},
+      {0, "A",      "normal",       1, "A"},
+      {0, "A/B",    "normal",       1, "A/B"},
+      {0, "A/B/C",  "normal",       1, "A/B/C", FALSE, "A/B/C2"},
+      {3, "A/B/C",  "base-deleted", NO_COPY_FROM},
+      {3, "A/B/C2", "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A/B", "A/B2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A"},
+      {0, "A/B",     "normal",       1, "A/B",   FALSE, "A/B2"},
+      {0, "A/B/C",   "normal",       1, "A/B/C", FALSE, "A/B2/C2"},
+      {2, "A/B",     "base-deleted", NO_COPY_FROM},
+      {2, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {2, "A/B2",    "normal",       1, "A/B",   MOVED_HERE},
+      {2, "A/B2/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {3, "A/B2/C",  "base-deleted", NO_COPY_FROM},
+      {3, "A/B2/C2", "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B",   FALSE, "A2/B2"},
+      {0, "A/B/C",   "normal",       1, "A/B/C", FALSE, "A2/B2/C2"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {2, "A2/B",    "base-deleted", NO_COPY_FROM},
+      {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
+      {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
+      {2, "A2/B2/C", "normal",       1, "A/B/C", MOVED_HERE},
+      {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
+      {3, "A2/B2/C2","normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  /* Revert should leave the A to A2 move */
+  SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B", svn_depth_infinity));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+nested_moves_child_last(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "nested_moves_child_last", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",      "normal", 1, ""},
+      {0, "A",     "normal", 1, "A"},
+      {0, "A/B",   "normal", 1, "A/B"},
+      {0, "A/B/C", "normal", 1, "A/B/C"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A2/B", "A2/B2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B",   FALSE, "A2/B2"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {2, "A2/B",    "base-deleted", NO_COPY_FROM},
+      {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
+      {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
+      {2, "A2/B2/C", "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B",   FALSE, "A2/B2"},
+      {0, "A/B/C",   "normal",       1, "A/B/C", FALSE, "A2/B2/C2"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {2, "A2/B",    "base-deleted", NO_COPY_FROM},
+      {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
+      {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
+      {2, "A2/B2/C", "normal",       1, "A/B/C", MOVED_HERE},
+      {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
+      {3, "A2/B2/C2","normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  /* Revert should leave the A to A2 move */
+  SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B", svn_depth_infinity));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_in_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_in_copy", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+  SVN_ERR(wc_copy(&b, "A", "A2"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",     "normal", 1, ""},
+      {0, "A",    "normal", 1, "A"},
+      {0, "A/B",  "normal", 1, "A/B"},
+      {1, "A2",   "normal", 1, "A"},
+      {1, "A2/B", "normal", 1, "A/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A2/B", "A2/B2")); /* ### Moved-here gets recorded, but
+                                            not moved-to. */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",      "normal",       1, ""},
+      {0, "A",     "normal",       1, "A"},
+      {0, "A/B",   "normal",       1, "A/B"},
+      {1, "A2",    "normal",       1, "A"},
+      {1, "A2/B",  "normal",       1, "A/B"},
+      {2, "A2/B",  "base-deleted", NO_COPY_FROM},
+      {2, "A2/B2", "normal",       1, "A/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_in_replace(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_in_replace", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "X"));
+  SVN_ERR(wc_mkdir(&b, "X/B"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+  SVN_ERR(wc_delete(&b, "A"));
+  SVN_ERR(wc_copy(&b, "X", "A"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal", 1, ""},
+      {0, "A",   "normal", 1, "A"},
+      {0, "A/B", "normal", 1, "A/B"},
+      {0, "X",   "normal", 1, "X"},
+      {0, "X/B", "normal", 1, "X/B"},
+      {1, "A",   "normal", 1, "X"},
+      {1, "A/B", "normal", 1, "X/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A/B", "A/B2")); /* ### Moved-to gets recorded on A/B
+                                          at op-depth=0, that's not the node
+                                          that got moved. */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",     "normal",       1, ""},
+      {0, "A",    "normal",       1, "A"},
+      {0, "A/B",  "normal",       1, "A/B"},
+      {0, "X",    "normal",       1, "X"},
+      {0, "X/B",  "normal",       1, "X/B"},
+      {1, "A",    "normal",       1, "X"},
+      {1, "A/B",  "normal",       1, "X/B"},
+      {2, "A/B",  "base-deleted", NO_COPY_FROM},
+      {2, "A/B2", "normal",       1, "X/B", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_a_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "copy_a_move", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",      "normal", 1, ""},
+      {0, "A",     "normal", 1, "A"},
+      {0, "A/B",   "normal", 1, "A/B"},
+      {0, "A/B/C", "normal", 1, "A/B/C"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  SVN_ERR(wc_move(&b, "A/B/C", "A/C2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",      "normal",       1, ""},
+      {0, "A",     "normal",       1, "A"},
+      {0, "A/B",   "normal",       1, "A/B"},
+      {0, "A/B/C", "normal",       1, "A/B/C", FALSE, "A/C2"},
+      {2, "A/C2",  "normal",       1, "A/B/C", MOVED_HERE},
+      {3, "A/B/C", "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+  /* Copying a move doesn't copy any moved-to/here artifacts, which
+     means that moving inside a copy is not the same as copying
+     something that contains a move?  Is this behaviour correct? */
+  SVN_ERR(wc_copy(&b, "A", "A2"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",       "normal",       1, ""},
+      {0, "A",      "normal",       1, "A"},
+      {0, "A/B",    "normal",       1, "A/B"},
+      {0, "A/B/C",  "normal",       1, "A/B/C", FALSE, "A/C2"},
+      {2, "A/C2",   "normal",       1, "A/B/C", MOVED_HERE},
+      {3, "A/B/C",  "base-deleted", NO_COPY_FROM},
+      {1, "A2",     "normal",       1, "A"},
+      {1, "A2/B",   "normal",       1, "A/B"},
+      {1, "A2/B/C", "normal",       1, "A/B/C"},
+      {2, "A2/C2",  "normal",       1, "A/B/C"},
+      {3, "A2/B/C", "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_to_swap(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_to_swap", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "X"));
+  SVN_ERR(wc_mkdir(&b, "X/Y"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_move(&b, "A/B", "X/B"));
+  SVN_ERR(wc_move(&b, "X/Y", "A/Y"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal",       1, ""},
+      {0, "A",   "normal",       1, "A"},
+      {0, "A/B", "normal",       1, "A/B", FALSE, "X/B"},
+      {0, "X",   "normal",       1, "X"},
+      {0, "X/Y", "normal",       1, "X/Y", FALSE, "A/Y"},
+      {2, "A/B", "base-deleted", NO_COPY_FROM},
+      {2, "A/Y", "normal",       1, "X/Y", MOVED_HERE},
+      {2, "X/Y", "base-deleted", NO_COPY_FROM},
+      {2, "X/B", "normal",       1, "A/B", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  SVN_ERR(wc_move(&b, "X", "A"));
+  SVN_ERR(wc_move(&b, "A2", "X"));
+
+  /* Is this correct or should A/Y and X/B at op-depth=1 be marked
+     moved-here? */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal",       1, ""},
+      {0, "A",   "normal",       1, "A",   FALSE, "X"},
+      {0, "A/B", "normal",       1, "A/B", FALSE, "A/B"},
+      {0, "X",   "normal",       1, "X",   FALSE, "A"},
+      {0, "X/Y", "normal",       1, "X/Y", FALSE, "X/Y"},
+      {1, "A",   "normal",       1, "X",   MOVED_HERE},
+      {1, "A/Y", "normal",       1, "X/Y", MOVED_HERE},
+      {1, "A/B", "base-deleted", NO_COPY_FROM},
+      {1, "X",   "normal",       1, "A",   MOVED_HERE},
+      {1, "X/B", "normal",       1, "A/B", MOVED_HERE},
+      {1, "X/Y", "base-deleted", NO_COPY_FROM},
+      {2, "A/Y", "base-deleted", NO_COPY_FROM},
+      {2, "X/B", "base-deleted", NO_COPY_FROM},
+      {2, "A/B", "normal",       1, "A/B", MOVED_HERE},
+      {2, "X/Y", "normal",       1, "X/Y", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  /* Revert and try in different order */
+  SVN_ERR(wc_revert(&b, "", svn_depth_infinity));
+
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  SVN_ERR(wc_move(&b, "X", "A"));
+  SVN_ERR(wc_move(&b, "A2", "X"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal",       1, ""},
+      {0, "A",   "normal",       1, "A",   FALSE, "X"},
+      {0, "A/B", "normal",       1, "A/B"},
+      {0, "X",   "normal",       1, "X",   FALSE, "A"},
+      {0, "X/Y", "normal",       1, "X/Y"},
+      {1, "A",   "normal",       1, "X",   MOVED_HERE},
+      {1, "A/Y", "normal",       1, "X/Y", MOVED_HERE},
+      {1, "A/B", "base-deleted", NO_COPY_FROM},
+      {1, "X",   "normal",       1, "A",   MOVED_HERE},
+      {1, "X/B", "normal",       1, "A/B", MOVED_HERE},
+      {1, "X/Y", "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(wc_move(&b, "A/Y", "X/Y"));
+  SVN_ERR(wc_move(&b, "X/B", "A/B"));
+  
+  {
+    nodes_row_t nodes[] = {
+      {0, "",    "normal",       1, ""},
+      {0, "A",   "normal",       1, "A",   FALSE, "X"},
+      {0, "A/B", "normal",       1, "A/B", FALSE, "A/B"},
+      {0, "X",   "normal",       1, "X",   FALSE, "A"},
+      {0, "X/Y", "normal",       1, "X/Y", FALSE, "X/Y"},
+      {1, "A",   "normal",       1, "X",   MOVED_HERE},
+      {1, "A/Y", "normal",       1, "X/Y", MOVED_HERE},
+      {1, "A/B", "base-deleted", NO_COPY_FROM},
+      {1, "X",   "normal",       1, "A",   MOVED_HERE},
+      {1, "X/B", "normal",       1, "A/B", MOVED_HERE},
+      {1, "X/Y", "base-deleted", NO_COPY_FROM},
+      {2, "A/Y", "base-deleted", NO_COPY_FROM},
+      {2, "X/B", "base-deleted", NO_COPY_FROM},
+      {2, "A/B", "normal",       1, "A/B", MOVED_HERE},
+      {2, "X/Y", "normal",       1, "X/Y", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+revert_nested_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+  nodes_row_t nodes_A_moved[] = {
+    {0, "",       "normal",       1, ""},
+    {0, "A",      "normal",       1, "A",     FALSE, "A2"},
+    {0, "A/B",    "normal",       1, "A/B"},
+    {0, "A/B/C",  "normal",       1, "A/B/C"},
+    {1, "A",      "base-deleted", NO_COPY_FROM},
+    {1, "A/B",    "base-deleted", NO_COPY_FROM},
+    {1, "A/B/C",  "base-deleted", NO_COPY_FROM},
+    {1, "A2",     "normal",       1, "A",     MOVED_HERE},
+    {1, "A2/B",   "normal",       1, "A/B",   MOVED_HERE},
+    {1, "A2/B/C", "normal",       1, "A/B/C", MOVED_HERE},
+    {0}
+  };
+  nodes_row_t nodes_AB_moved[] = {
+    {0, "",        "normal",       1, ""},
+    {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+    {0, "A/B",     "normal",       1, "A/B",   FALSE, "A2/B2"},
+    {0, "A/B/C",   "normal",       1, "A/B/C"},
+    {1, "A",       "base-deleted", NO_COPY_FROM},
+    {1, "A/B",     "base-deleted", NO_COPY_FROM},
+    {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+    {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+    {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+    {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+    {2, "A2/B",    "base-deleted", NO_COPY_FROM},
+    {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
+    {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
+    {2, "A2/B2/C", "normal",       1, "A/B/C", MOVED_HERE},
+    {0}
+  };
+  nodes_row_t nodes_ABC_moved[] = {
+    {0, "",         "normal",       1, ""},
+    {0, "A",        "normal",       1, "A",     FALSE, "A2"},
+    {0, "A/B",      "normal",       1, "A/B",   FALSE, "A2/B2"},
+    {0, "A/B/C",    "normal",       1, "A/B/C", FALSE, "A2/B2/C2"},
+    {1, "A",        "base-deleted", NO_COPY_FROM},
+    {1, "A/B",      "base-deleted", NO_COPY_FROM},
+    {1, "A/B/C",    "base-deleted", NO_COPY_FROM},
+    {1, "A2",       "normal",       1, "A",     MOVED_HERE},
+    {1, "A2/B",     "normal",       1, "A/B",   MOVED_HERE},
+    {1, "A2/B/C",   "normal",       1, "A/B/C", MOVED_HERE},
+    {2, "A2/B",     "base-deleted", NO_COPY_FROM},
+    {2, "A2/B/C",   "base-deleted", NO_COPY_FROM},
+    {2, "A2/B2",    "normal",       1, "A/B",   MOVED_HERE},
+    {2, "A2/B2/C",  "normal",       1, "A/B/C", MOVED_HERE},
+    {3, "A2/B2/C",  "base-deleted", NO_COPY_FROM},
+    {3, "A2/B2/C2", "normal",       1, "A/B/C", MOVED_HERE},
+    {0}
+  };
+
+  SVN_ERR(svn_test__sandbox_create(&b, "revert_nested_move", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+
+  SVN_ERR(wc_move(&b, "A2/B", "A2/B2"));
+  SVN_ERR(check_db_rows(&b, "", nodes_AB_moved));
+
+  SVN_ERR(wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+  SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
+  SVN_ERR(wc_revert(&b, "A2/B", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
+  SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+
+  SVN_ERR(wc_move(&b, "A2/B", "A2/B2"));
+  SVN_ERR(wc_move(&b, "A2/B2/C", "A2/B2/C2"));
+  SVN_ERR(check_db_rows(&b, "", nodes_ABC_moved));
+
+  SVN_ERR(wc_revert(&b, "A2/B2/C", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B2/C2", svn_depth_infinity));
+  SVN_ERR(check_db_rows(&b, "", nodes_AB_moved));
+
+  SVN_ERR(wc_revert(&b, "A2/B", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
+  SVN_ERR(check_db_rows(&b, "", nodes_A_moved));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_on_move(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_on_move", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "X"));
+  SVN_ERR(wc_mkdir(&b, "X/B"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_move(&b, "A/B", "B2"));
+  SVN_ERR(wc_delete(&b, "A"));
+  SVN_ERR(wc_copy(&b, "X", "A"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",         "normal",       1, ""},
+      {0, "A",        "normal",       1, "A"},
+      {0, "A/B",      "normal",       1, "A/B", FALSE, "B2"},
+      {0, "X",        "normal",       1, "X"},
+      {0, "X/B",      "normal",       1, "X/B"},
+      {1, "B2",       "normal",       1, "A/B", MOVED_HERE},
+      {1, "A",        "normal",       1, "X"},
+      {1, "A/B",      "normal",       1, "X/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  /* A/B to B2 is already recorded in A/B but the copy has given us
+     another A/B that we can move.  A second move overwites the first
+     move stored in A/B even though it's a different node being moved,
+     and that breaks the recording of the move to B2. */
+  SVN_ERR(wc_move(&b, "A/B", "B3"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",         "normal",       1, ""},
+      {0, "A",        "normal",       1, "A"},
+      {0, "A/B",      "normal",       1, "A/B",   FALSE, "B2"}, /* XFAIL */
+      {0, "X",        "normal",       1, "X"},
+      {0, "X/B",      "normal",       1, "X/B"},
+      {1, "B2",       "normal",       1, "A/B",   MOVED_HERE},
+      {1, "B3",       "normal",       1, "X/B",   MOVED_HERE},
+      {1, "A",        "normal",       1, "X"},
+      {1, "A/B",      "normal",       1, "X/B"},         /* moved_to=B3? */
+      {2, "A/B",      "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_on_move2(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_on_move2", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_mkdir(&b, "X"));
+  SVN_ERR(wc_mkdir(&b, "X/B"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  SVN_ERR(wc_delete(&b, "A"));
+  SVN_ERR(wc_copy(&b, "X", "A"));
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",         "normal",       1, ""},
+      {0, "A",        "normal",       1, "A",   FALSE, "A2"},
+      {0, "A/B",      "normal",       1, "A/B"},
+      {0, "X",        "normal",       1, "X"},
+      {0, "X/B",      "normal",       1, "X/B"},
+      {1, "A2",       "normal",       1, "A",   MOVED_HERE},
+      {1, "A2/B",     "normal",       1, "A/B", MOVED_HERE},
+      {1, "A",        "normal",       1, "X"},
+      {1, "A/B",      "normal",       1, "X/B"},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  /* A/B is already moved to A2/B but there is no explicit moved_to,
+     we derive it from A.  The copy has given us another A/B that we
+     can move doing so stores explicit moved_to in A/B that breaks the
+     recording of the first move to A2/B. */
+  SVN_ERR(wc_move(&b, "A/B", "B3"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",         "normal",       1, ""},
+      {0, "A",        "normal",       1, "A",   FALSE, "A2"},
+      {0, "A/B",      "normal",       1, "A/B"},               /* XFAIL */
+      {0, "X",        "normal",       1, "X"},
+      {0, "X/B",      "normal",       1, "X/B"},
+      {1, "A2",       "normal",       1, "A",   MOVED_HERE},
+      {1, "A2/B",     "normal",       1, "A/B", MOVED_HERE},
+      {1, "B3",       "normal",       1, "X/B", MOVED_HERE},
+      {1, "A",        "normal",       1, "X"},
+      {1, "A/B",      "normal",       1, "X/B"},           /* moved_to=B3? */
+      {2, "A/B",      "base-deleted", NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_added(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_added", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  SVN_ERR(wc_mkdir(&b, "A2/B/C2"));
+
+  /* Both A2/B/C and A2/B/C2 are simple adds inside the move.  It
+     doesn't seem right for A2/B/C to be marked moved_here. */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",         "normal",       1, ""},
+      {0, "A",        "normal",       1, "A",   FALSE, "A2"},
+      {0, "A/B",      "normal",       1, "A/B"},
+      {1, "A",        "base-deleted", NO_COPY_FROM},
+      {1, "A/B",      "base-deleted", NO_COPY_FROM},
+      {1, "A2",       "normal",       1, "A",   MOVED_HERE},
+      {1, "A2/B",     "normal",       1, "A/B", MOVED_HERE},
+      {3, "A2/B/C",   "normal",       NO_COPY_FROM},          /* XFAIL */
+      {3, "A2/B/C2",  "normal",       NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -3715,7 +4514,7 @@ struct svn_test_descriptor_t test_funcs[
                        "test_op_delete"),
     SVN_TEST_OPTS_PASS(test_child_replace_with_same_origin,
                        "test_child_replace_with_same"),
-    SVN_TEST_OPTS_PASS(test_shadowed_update,
+    SVN_TEST_OPTS_XFAIL(test_shadowed_update,
                        "test_shadowed_update"),
     SVN_TEST_OPTS_PASS(test_copy_of_deleted,
                        "test_copy_of_deleted (issue #3873)"),
@@ -3735,5 +4534,27 @@ struct svn_test_descriptor_t test_funcs[
                        "copy_file_externals"),
     SVN_TEST_OPTS_PASS(copy_wc_wc_absent,
                        "test_wc_wc_copy_absent"),
+    SVN_TEST_OPTS_PASS(incomplete_switch,
+                       "incomplete_switch (issue 4040)"),
+    SVN_TEST_OPTS_PASS(nested_moves_child_first,
+                       "nested_moves_child_first"),
+    SVN_TEST_OPTS_PASS(nested_moves_child_last,
+                       "nested_moves_child_last"),
+    SVN_TEST_OPTS_XFAIL(move_in_copy,
+                       "move_in_copy"),
+    SVN_TEST_OPTS_XFAIL(move_in_replace,
+                       "move_in_replace"),
+    SVN_TEST_OPTS_PASS(copy_a_move,
+                       "copy_a_move"),
+    SVN_TEST_OPTS_PASS(move_to_swap,
+                       "move_to_swap"),
+    SVN_TEST_OPTS_PASS(revert_nested_move,
+                       "revert_nested_move"),
+    SVN_TEST_OPTS_XFAIL(move_on_move,
+                       "move_on_move"),
+    SVN_TEST_OPTS_XFAIL(move_on_move2,
+                       "move_on_move2"),
+    SVN_TEST_OPTS_XFAIL(move_added,
+                       "move_added"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/fs-py/subversion/tests/svn_test_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/svn_test_fs.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/svn_test_fs.c (original)
+++ subversion/branches/fs-py/subversion/tests/svn_test_fs.c Mon Dec 19 18:49:34 2011
@@ -251,7 +251,7 @@ svn_test__stream_to_string(svn_stringbuf
                    of priorities today, though. */
 
   apr_size_t len;
-  svn_stringbuf_t *str = svn_stringbuf_create("", pool);
+  svn_stringbuf_t *str = svn_stringbuf_create_empty(pool);
 
   do
     {
@@ -442,7 +442,7 @@ svn_test__validate_tree(svn_fs_root_t *r
             {
               /* If we don't have a corrupt entries string, make one. */
               if (! corrupt_entries)
-                corrupt_entries = svn_stringbuf_create("", subpool);
+                corrupt_entries = svn_stringbuf_create_empty(subpool);
 
               /* Append this entry name to the list of corrupt entries. */
               svn_stringbuf_appendcstr(corrupt_entries, "   ");
@@ -458,7 +458,7 @@ svn_test__validate_tree(svn_fs_root_t *r
         {
           /* If we don't have a missing entries string, make one. */
           if (! missing_entries)
-            missing_entries = svn_stringbuf_create("", subpool);
+            missing_entries = svn_stringbuf_create_empty(subpool);
 
           /* Append this entry name to the list of missing entries. */
           svn_stringbuf_appendcstr(missing_entries, "   ");
@@ -481,7 +481,7 @@ svn_test__validate_tree(svn_fs_root_t *r
 
       /* If we don't have an extra entries string, make one. */
       if (! extra_entries)
-        extra_entries = svn_stringbuf_create("", subpool);
+        extra_entries = svn_stringbuf_create_empty(subpool);
 
       /* Append this entry name to the list of missing entries. */
       svn_stringbuf_appendcstr(extra_entries, "   ");

Modified: subversion/branches/fs-py/tools/client-side/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/tools/client-side/svnmucc/svnmucc.c?rev=1220893&r1=1220892&r2=1220893&view=diff
==============================================================================
--- subversion/branches/fs-py/tools/client-side/svnmucc/svnmucc.c (original)
+++ subversion/branches/fs-py/tools/client-side/svnmucc/svnmucc.c Mon Dec 19 18:49:34 2011
@@ -109,6 +109,7 @@ create_ra_callbacks(svn_ra_callbacks2_t 
                     const char *username,
                     const char *password,
                     const char *config_dir,
+                    svn_config_t *cfg_config,
                     svn_boolean_t non_interactive,
                     svn_boolean_t no_auth_cache,
                     apr_pool_t *pool)
@@ -119,7 +120,8 @@ create_ra_callbacks(svn_ra_callbacks2_t 
                                         non_interactive,
                                         username, password, config_dir,
                                         no_auth_cache,
-                                        FALSE, NULL, NULL, NULL, pool));
+                                        FALSE /* trust_server_certs */,
+                                        cfg_config, NULL, NULL, pool));
 
   (*callbacks)->open_tmp_file = open_tmp_file;
 
@@ -629,13 +631,17 @@ execute(const apr_array_header_t *action
   struct operation root;
   svn_error_t *err;
   apr_hash_t *config;
+  svn_config_t *cfg_config;
   int i;
 
   SVN_ERR(svn_config_get_config(&config, config_dir, pool));
   SVN_ERR(svn_cmdline__apply_config_options(config, config_options,
                                             "svnmucc: ", "--config-option"));
+  cfg_config = apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,
+                            APR_HASH_KEY_STRING);
   SVN_ERR(create_ra_callbacks(&ra_callbacks, username, password, config_dir,
-                              non_interactive, no_auth_cache, pool));
+                              cfg_config, non_interactive, no_auth_cache,
+                              pool));
   SVN_ERR(svn_ra_open4(&session, NULL, anchor, NULL, ra_callbacks,
                        NULL, config, pool));
 



Mime
View raw message