You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/05/16 22:32:54 UTC

svn commit: r1339349 [28/37] - in /subversion/branches/fix-rdump-editor: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/client-side/vim/ contrib/server-side/ notes/ notes/api-errat...

Modified: subversion/branches/fix-rdump-editor/subversion/svnsync/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/subversion/svnsync/main.c?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/subversion/svnsync/main.c (original)
+++ subversion/branches/fix-rdump-editor/subversion/svnsync/main.c Wed May 16 20:32:43 2012
@@ -959,16 +959,21 @@ open_target_session(svn_ra_session_t **t
 typedef struct replay_baton_t {
   svn_ra_session_t *from_session;
   svn_ra_session_t *to_session;
+  /* Extra 'backdoor' session for fetching data *from* the target repo. */
+  svn_ra_session_t *extra_to_session;
+  svn_revnum_t current_revision;
   subcommand_baton_t *sb;
   svn_boolean_t has_commit_revprops_capability;
   int normalized_rev_props_count;
   int normalized_node_props_count;
+  const char *to_root;
 } replay_baton_t;
 
 /* Return a replay baton allocated from POOL and populated with
    data from the provided parameters. */
-static replay_baton_t *
-make_replay_baton(svn_ra_session_t *from_session,
+static svn_error_t *
+make_replay_baton(replay_baton_t **baton_p,
+                  svn_ra_session_t *from_session,
                   svn_ra_session_t *to_session,
                   subcommand_baton_t *sb, apr_pool_t *pool)
 {
@@ -976,7 +981,16 @@ make_replay_baton(svn_ra_session_t *from
   rb->from_session = from_session;
   rb->to_session = to_session;
   rb->sb = sb;
-  return rb;
+
+  SVN_ERR(svn_ra_get_repos_root2(to_session, &rb->to_root, pool));
+
+#ifdef ENABLE_EV2_SHIMS
+  /* Open up the extra baton.  Only needed for Ev2 shims. */
+  SVN_ERR(open_target_session(&rb->extra_to_session, sb, pool));
+#endif
+
+  *baton_p = rb;
+  return SVN_NO_ERROR;
 }
 
 /* Return TRUE iff KEY is the name of an svn:date or svn:author or any svnsync
@@ -1030,6 +1044,137 @@ filter_include_log(const char *key)
 }
 
 
+static svn_error_t *
+fetch_base_func(const char **filename,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  struct replay_baton_t *rb = baton;
+  svn_stream_t *fstream;
+  svn_error_t *err;
+
+  if (svn_path_is_url(path))
+    path = svn_uri_skip_ancestor(rb->to_root, path, scratch_pool);
+  else if (path[0] == '/')
+    path += 1;
+
+  if (! SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = rb->current_revision - 1;
+
+  SVN_ERR(svn_stream_open_unique(&fstream, filename, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 result_pool, scratch_pool));
+
+  err = svn_ra_get_file(rb->extra_to_session, path, base_revision,
+                        fstream, NULL, NULL, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      SVN_ERR(svn_stream_close(fstream));
+
+      *filename = NULL;
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
+
+  SVN_ERR(svn_stream_close(fstream));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fetch_props_func(apr_hash_t **props,
+                 void *baton,
+                 const char *path,
+                 svn_revnum_t base_revision,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct replay_baton_t *rb = baton;
+  svn_node_kind_t node_kind;
+
+  if (svn_path_is_url(path))
+    path = svn_uri_skip_ancestor(rb->to_root, path, scratch_pool);
+  else if (path[0] == '/')
+    path += 1;
+
+  if (! SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = rb->current_revision - 1;
+
+  SVN_ERR(svn_ra_check_path(rb->extra_to_session, path, base_revision,
+                            &node_kind, scratch_pool));
+
+  if (node_kind == svn_node_file)
+    {
+      SVN_ERR(svn_ra_get_file(rb->extra_to_session, path, base_revision,
+                              NULL, NULL, props, result_pool));
+    }
+  else if (node_kind == svn_node_dir)
+    {
+      apr_array_header_t *tmp_props;
+
+      SVN_ERR(svn_ra_get_dir2(rb->extra_to_session, NULL, NULL, props, path,
+                              base_revision, 0 /* Dirent fields */,
+                              result_pool));
+      tmp_props = svn_prop_hash_to_array(*props, result_pool);
+      SVN_ERR(svn_categorize_props(tmp_props, NULL, NULL, &tmp_props,
+                                   result_pool));
+      *props = svn_prop_array_to_hash(tmp_props, result_pool);
+    }
+  else
+    {
+      *props = apr_hash_make(result_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fetch_kind_func(svn_kind_t *kind,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *scratch_pool)
+{
+  struct replay_baton_t *rb = baton;
+  svn_node_kind_t node_kind;
+
+  if (svn_path_is_url(path))
+    path = svn_uri_skip_ancestor(rb->to_root, path, scratch_pool);
+  else if (path[0] == '/')
+    path += 1;
+
+  if (! SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = rb->current_revision - 1;
+
+  SVN_ERR(svn_ra_check_path(rb->extra_to_session, path, base_revision,
+                            &node_kind, scratch_pool));
+
+  *kind = svn__kind_from_node_kind(node_kind, FALSE);
+  return SVN_NO_ERROR;
+}
+
+
+static svn_delta_shim_callbacks_t *
+get_shim_callbacks(replay_baton_t *rb,
+                   apr_pool_t *result_pool)
+{
+  svn_delta_shim_callbacks_t *callbacks =
+                            svn_delta_shim_callbacks_default(result_pool);
+
+  callbacks->fetch_props_func = fetch_props_func;
+  callbacks->fetch_kind_func = fetch_kind_func;
+  callbacks->fetch_base_func = fetch_base_func;
+  callbacks->fetch_baton = rb;
+
+  return callbacks;
+}
+
+
 /* Callback function for svn_ra_replay_range, invoked when starting to parse
  * a replay report.
  */
@@ -1096,6 +1241,8 @@ replay_rev_started(svn_revnum_t revision
                                      rb->sb->source_prop_encoding, pool));
   rb->normalized_rev_props_count += normalized_count;
 
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(rb->to_session,
+                                get_shim_callbacks(rb, pool)));
   SVN_ERR(svn_ra_get_commit_editor3(rb->to_session, &commit_editor,
                                     &commit_baton,
                                     filtered,
@@ -1118,6 +1265,7 @@ replay_rev_started(svn_revnum_t revision
   *editor = cancel_editor;
   *edit_baton = cancel_baton;
 
+  rb->current_revision = revision;
   return SVN_NO_ERROR;
 }
 
@@ -1311,7 +1459,7 @@ do_synchronize(svn_ra_session_t *to_sess
 
   /* Ok, so there are new revisions, iterate over them copying them
      into the destination repository. */
-  rb = make_replay_baton(from_session, to_session, baton, pool);
+  SVN_ERR(make_replay_baton(&rb, from_session, to_session, baton, pool));
 
   /* For compatibility with older svnserve versions, check first if we
      support adding revprops to the commit. */
@@ -1740,7 +1888,6 @@ main(int argc, const char *argv[])
   const char *password = NULL, *source_password = NULL, *sync_password = NULL;
   apr_array_header_t *config_options = NULL;
   const char *source_prop_encoding = NULL;
-  apr_allocator_t *allocator;
 
   if (svn_cmdline_init("svnsync", stderr) != EXIT_SUCCESS)
     {
@@ -1754,13 +1901,7 @@ main(int argc, const char *argv[])
   /* Create our top-level pool.  Use a separate mutexless allocator,
    * given this application is single threaded.
    */
-  if (apr_allocator_create(&allocator))
-    return EXIT_FAILURE;
-
-  apr_allocator_max_free_set(allocator, SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
-
-  pool = svn_pool_create_ex(NULL, allocator);
-  apr_allocator_owner_set(allocator, pool);
+  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
   err = svn_ra_initialize(pool);
   if (err)

Modified: subversion/branches/fix-rdump-editor/subversion/svnsync/sync.c
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/subversion/svnsync/sync.c?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/subversion/svnsync/sync.c (original)
+++ subversion/branches/fix-rdump-editor/subversion/svnsync/sync.c Wed May 16 20:32:43 2012
@@ -225,9 +225,7 @@ add_directory(const char *path,
   edit_baton_t *eb = pb->edit_baton;
   node_baton_t *b = apr_palloc(pool, sizeof(*b));
 
-  /* if copyfrom_path starts with '/' join rest of copyfrom_path leaving
-   * leading '/' with canonicalized url eb->to_url.
-   */
+  /* if copyfrom_path is an fspath create a proper uri */
   if (copyfrom_path && copyfrom_path[0] == '/')
     copyfrom_path = svn_path_url_add_component2(eb->to_url,
                                                 copyfrom_path + 1, pool);
@@ -276,9 +274,10 @@ add_file(const char *path,
   edit_baton_t *eb = pb->edit_baton;
   node_baton_t *fb = apr_palloc(pool, sizeof(*fb));
 
-  if (copyfrom_path)
-    copyfrom_path = apr_psprintf(pool, "%s%s", eb->to_url,
-                                 svn_path_uri_encode(copyfrom_path, pool));
+  /* if copyfrom_path is an fspath create a proper uri */
+  if (copyfrom_path && copyfrom_path[0] == '/')
+    copyfrom_path = svn_path_url_add_component2(eb->to_url,
+                                                copyfrom_path + 1, pool);
 
   SVN_ERR(eb->wrapped_editor->add_file(path, pb->wrapped_node_baton,
                                        copyfrom_path, copyfrom_rev,
@@ -386,7 +385,7 @@ change_file_prop(void *file_baton,
   edit_baton_t *eb = fb->edit_baton;
 
   /* only regular properties can pass over libsvn_ra */
-  if (svn_property_kind(NULL, name) != svn_prop_regular_kind)
+  if (svn_property_kind2(name) != svn_prop_regular_kind)
     return SVN_NO_ERROR;
 
   /* Maybe drop svn:mergeinfo.  */
@@ -434,7 +433,7 @@ change_dir_prop(void *dir_baton,
   edit_baton_t *eb = db->edit_baton;
 
   /* Only regular properties can pass over libsvn_ra */
-  if (svn_property_kind(NULL, name) != svn_prop_regular_kind)
+  if (svn_property_kind2(name) != svn_prop_regular_kind)
     return SVN_NO_ERROR;
 
   /* Maybe drop svn:mergeinfo.  */

Modified: subversion/branches/fix-rdump-editor/subversion/svnversion/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/subversion/svnversion/main.c?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/subversion/svnversion/main.c (original)
+++ subversion/branches/fix-rdump-editor/subversion/svnversion/main.c Wed May 16 20:32:43 2012
@@ -122,7 +122,6 @@ main(int argc, const char *argv[])
 {
   const char *wc_path, *trail_url;
   const char *local_abspath;
-  apr_allocator_t *allocator;
   apr_pool_t *pool;
   svn_wc_revision_status_t *res;
   svn_boolean_t no_newline = FALSE, committed = FALSE;
@@ -150,13 +149,7 @@ main(int argc, const char *argv[])
   /* Create our top-level pool.  Use a separate mutexless allocator,
    * given this application is single threaded.
    */
-  if (apr_allocator_create(&allocator))
-    return EXIT_FAILURE;
-
-  apr_allocator_max_free_set(allocator, SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
-
-  pool = svn_pool_create_ex(NULL, allocator);
-  apr_allocator_owner_set(allocator, pool);
+  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
   /* Check library versions */
   err = check_lib_versions();

Modified: subversion/branches/fix-rdump-editor/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/subversion/tests/cmdline/authz_tests.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/fix-rdump-editor/subversion/tests/cmdline/authz_tests.py Wed May 16 20:32:43 2012
@@ -1398,6 +1398,59 @@ def upgrade_absent(sbox):
   svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
                                         None, None)
 
+@Issue(4183)
+@XFail()
+@Skip(svntest.main.is_ra_type_file)
+def remove_subdir_with_authz_and_tc(sbox):
+  "remove a subdir with authz file"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_rm('A/B')
+  sbox.simple_commit()
+
+  svntest.main.write_restrictive_svnserve_conf(sbox.repo_dir)
+  svntest.main.write_authz_file(sbox, { "/"      : "*=rw",
+                                        "/A/B/E" : "*="})
+
+  # Now update back to r1. This will reintroduce A/B except A/B/E.
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B'               : Item(status='A '),
+    'A/B/F'             : Item(status='A '),
+    'A/B/lambda'        : Item(status='A '),
+  })
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None,
+                                        None, None,
+                                        None, None, False,
+                                        wc_dir, '-r', '1')
+
+  # Perform some edit operation to introduce a tree conflict
+  svntest.main.file_write(sbox.ospath('A/B/lambda'), 'qq')
+
+  # And now update to r2. This tries to delete A/B and causes a tree conflict
+  # ### But is also causes an error in creating the copied state
+  # ###  svn: E220001: Cannot copy '<snip>\A\B\E' excluded by server
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B'               : Item(status='  ', treeconflict='C'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        None,
+                                        None,
+                                        None, None,
+                                        None, None, False,
+                                        wc_dir)
+
 ########################################################################
 # Run the tests
 
@@ -1427,6 +1480,7 @@ test_list = [ None,
               wc_delete,
               wc_commit_error_handling,
               upgrade_absent,
+              remove_subdir_with_authz_and_tc
              ]
 serial_only = True
 

Modified: subversion/branches/fix-rdump-editor/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/subversion/tests/cmdline/basic_tests.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/fix-rdump-editor/subversion/tests/cmdline/basic_tests.py Wed May 16 20:32:43 2012
@@ -25,7 +25,9 @@
 ######################################################################
 
 # General modules
-import shutil, stat, re, os
+import shutil, stat, re, os, logging
+
+logger = logging.getLogger()
 
 # Our testing module
 import svntest
@@ -65,11 +67,11 @@ def basic_checkout(sbox):
                                      wc_dir)
 
   # Make some changes to the working copy
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  mu_path = sbox.ospath('A/mu')
   svntest.main.file_append(mu_path, 'appended mu text')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
+  lambda_path = sbox.ospath('A/B/lambda')
   os.remove(lambda_path)
-  G_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  G_path = sbox.ospath('A/D/G')
 
   svntest.actions.run_and_verify_svn(None, None, [], 'rm', G_path)
 
@@ -108,7 +110,7 @@ def basic_status(sbox):
 
   svntest.actions.run_and_verify_status(wc_dir, output)
 
-  os.chdir(os.path.join(wc_dir, 'A'))
+  os.chdir(sbox.ospath('A'))
   output = svntest.actions.get_virginal_state("..", 1)
   svntest.actions.run_and_verify_status("..", output)
 
@@ -121,8 +123,8 @@ def basic_commit(sbox):
   wc_dir = sbox.wc_dir
 
   # Make a couple of local mods to files
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
+  mu_path = sbox.ospath('A/mu')
+  rho_path = sbox.ospath('A/D/G/rho')
   svntest.main.file_append(mu_path, 'appended mu text')
   svntest.main.file_append(rho_path, 'new appended text for rho')
 
@@ -157,8 +159,8 @@ def basic_update(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_backup)
 
   # Make a couple of local mods to files
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
+  mu_path = sbox.ospath('A/mu')
+  rho_path = sbox.ospath('A/D/G/rho')
   svntest.main.file_append(mu_path, 'appended mu text')
   svntest.main.file_append(rho_path, 'new appended text for rho')
 
@@ -203,7 +205,7 @@ def basic_update(sbox):
 
   # Unversioned paths, those that are not immediate children of a versioned
   # path, are skipped and do not raise an error
-  xx_path = os.path.join(wc_dir, 'xx', 'xx')
+  xx_path = sbox.ospath('xx/xx')
   exit_code, out, err = svntest.actions.run_and_verify_svn(
     "update xx/xx",
     ["Skipped '"+xx_path+"'\n",
@@ -324,7 +326,7 @@ def basic_mkdir_wc_with_parents(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  Y_Z_path = os.path.join(wc_dir, 'Y', 'Z')
+  Y_Z_path = sbox.ospath('Y/Z')
 
   svntest.actions.run_and_verify_svn("erroneous mkdir dir/subdir", [],
                                      ".*Try 'svn mkdir --parents' instead.*",
@@ -344,8 +346,8 @@ def basic_mkdir_wc_with_parents(sbox):
 
 
 #----------------------------------------------------------------------
-def basic_corruption(sbox):
-  "basic corruption detection"
+def basic_commit_corruption(sbox):
+  "basic corruption detection on commit"
 
   ## I always wanted a test named "basic_corruption". :-)
   ## Here's how it works:
@@ -356,21 +358,14 @@ def basic_corruption(sbox):
   ##    3. Intentionally corrupt `first/A/.svn/text-base/mu.svn-base'.
   ##    4. Try to commit, expect a failure.
   ##    5. Repair the text-base, commit again, expect success.
-  ##    6. Intentionally corrupt `second/A/.svn/text-base/mu.svn-base'.
-  ##    7. Try to update `second', expect failure.
-  ##    8. Repair the text-base, update again, expect success.
   ##
   ## Here we go...
 
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  # Make the "other" working copy
-  other_wc = sbox.add_wc_path('other')
-  svntest.actions.duplicate_dir(wc_dir, other_wc)
-
   # Make a local mod to mu
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  mu_path = sbox.ospath('A/mu')
   svntest.main.file_append(mu_path, 'appended mu text')
 
   # Created expected output tree for 'svn ci'
@@ -415,6 +410,48 @@ def basic_corruption(sbox):
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
 
+#----------------------------------------------------------------------
+def basic_update_corruption(sbox):
+  "basic corruption detection on update"
+
+  ## I always wanted a test named "basic_corruption". :-)
+  ## Here's how it works:
+  ##
+  ##    1. Make a working copy at rev 1, duplicate it.  Now we have
+  ##        two working copies at rev 1.  Call them first and second.
+  ##    2. Make a local mod to `first/A/mu'.
+  ##    3. Repair the text-base, commit again, expect success.
+  ##    4. Intentionally corrupt `second/A/.svn/text-base/mu.svn-base'.
+  ##    5. Try to update `second', expect failure.
+  ##    6. Repair the text-base, update again, expect success.
+  ##
+  ## Here we go...
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Make the "other" working copy
+  other_wc = sbox.add_wc_path('other')
+  svntest.actions.duplicate_dir(wc_dir, other_wc)
+
+  # Make a local mod to mu
+  mu_path = sbox.ospath('A/mu')
+  svntest.main.file_append(mu_path, 'appended mu text')
+
+  # Created expected output tree for 'svn ci'
+  expected_output = wc.State(wc_dir, {
+    'A/mu' : Item(verb='Sending'),
+    })
+
+  # Create expected status tree; all local revisions should be at 1,
+  # but mu should be at revision 2.
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', wc_rev=2)
+
+  # This commit should succeed.
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+
   # Create expected output tree for an update of the other_wc.
   expected_output = wc.State(other_wc, {
     'A/mu' : Item(status='U '),
@@ -474,8 +511,8 @@ def basic_merging_update(sbox):
   wc_dir = sbox.wc_dir
 
   # First change the greek tree to make two files 10 lines long
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
+  mu_path = sbox.ospath('A/mu')
+  rho_path = sbox.ospath('A/D/G/rho')
   mu_text = ""
   rho_text = ""
   for x in range(2,11):
@@ -580,8 +617,8 @@ def basic_conflict(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_backup)
 
   # Make a couple of local mods to files which will be committed
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
+  mu_path = sbox.ospath('A/mu')
+  rho_path = sbox.ospath('A/D/G/rho')
   svntest.main.file_append(mu_path, 'Original appended text for mu\n')
   svntest.main.file_append(rho_path, 'Original appended text for rho\n')
 
@@ -659,8 +696,8 @@ def basic_conflict(sbox):
     # probably reveal the cause for the failure, if they were
     # uncommented:
     #
-    # print("Not all extra reject files have been accounted for:")
-    # print(extra_files)
+    # logger.warn("Not all extra reject files have been accounted for:")
+    # logger.warn(extra_files)
     ### we should raise a less generic error here. which?
     raise svntest.Failure
 
@@ -687,9 +724,9 @@ def basic_cleanup(sbox):
   wc_dir = sbox.wc_dir
 
   # Lock some directories.
-  B_path = os.path.join(wc_dir, 'A', 'B')
-  G_path = os.path.join(wc_dir, 'A', 'D', 'G')
-  C_path = os.path.join(wc_dir, 'A', 'C')
+  B_path = sbox.ospath('A/B')
+  G_path = sbox.ospath('A/D/G')
+  C_path = sbox.ospath('A/C')
   svntest.actions.lock_admin_dir(B_path)
   svntest.actions.lock_admin_dir(G_path)
   svntest.actions.lock_admin_dir(C_path)
@@ -725,11 +762,11 @@ def basic_revert(sbox):
   wc_dir = sbox.wc_dir
 
   # Modify some files and props.
-  beta_path = os.path.join(wc_dir, 'A', 'B', 'E', 'beta')
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
-  iota_path = os.path.join(wc_dir, 'iota')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
-  zeta_path = os.path.join(wc_dir, 'A', 'D', 'H', 'zeta')
+  beta_path = sbox.ospath('A/B/E/beta')
+  gamma_path = sbox.ospath('A/D/gamma')
+  iota_path = sbox.ospath('iota')
+  rho_path = sbox.ospath('A/D/G/rho')
+  zeta_path = sbox.ospath('A/D/H/zeta')
   svntest.main.file_append(beta_path, "Added some text to 'beta'.\n")
   svntest.main.file_append(iota_path, "Added some text to 'iota'.\n")
   svntest.main.file_append(rho_path, "Added some text to 'rho'.\n")
@@ -780,17 +817,17 @@ def basic_revert(sbox):
   fp = open(beta_path, 'r')
   lines = fp.readlines()
   if not ((len (lines) == 1) and (lines[0] == "This is the file 'beta'.\n")):
-    print("Revert failed to restore original text.")
+    logger.warn("Revert failed to restore original text.")
     raise svntest.Failure
   fp = open(iota_path, 'r')
   lines = fp.readlines()
   if not ((len (lines) == 1) and (lines[0] == "This is the file 'iota'.\n")):
-    print("Revert failed to restore original text.")
+    logger.warn("Revert failed to restore original text.")
     raise svntest.Failure
   fp = open(rho_path, 'r')
   lines = fp.readlines()
   if not ((len (lines) == 1) and (lines[0] == "This is the file 'rho'.\n")):
-    print("Revert failed to restore original text.")
+    logger.warn("Revert failed to restore original text.")
     raise svntest.Failure
   fp = open(zeta_path, 'r')
   lines = fp.readlines()
@@ -806,7 +843,7 @@ def basic_revert(sbox):
 
   # Check that a directory scheduled to be added, but physically
   # removed, can be reverted.
-  X_path = os.path.join(wc_dir, 'X')
+  X_path = sbox.ospath('X')
 
   svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', X_path)
 
@@ -824,7 +861,7 @@ def basic_revert(sbox):
 
   # Check that a directory scheduled for deletion, but physically
   # removed, can be reverted.
-  E_path = os.path.join(wc_dir, 'A', 'B', 'E')
+  E_path = sbox.ospath('A/B/E')
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
 
   ### Most of the rest of this test is ineffective, due to the
@@ -890,7 +927,7 @@ def basic_switch(sbox):
   ### Switch the file `iota' to `A/D/gamma'.
 
   # Construct some paths for convenience
-  iota_path = os.path.join(wc_dir, 'iota')
+  iota_path = sbox.ospath('iota')
   gamma_url = sbox.repo_url + '/A/D/gamma'
 
   # Create expected output tree
@@ -924,7 +961,7 @@ def basic_switch(sbox):
   ### Switch the directory `A/D/H' to `A/D/G'.
 
   # Construct some paths for convenience
-  ADH_path = os.path.join(wc_dir, 'A', 'D', 'H')
+  ADH_path = sbox.ospath('A/D/H')
   chi_path = os.path.join(ADH_path, 'chi')
   omega_path = os.path.join(ADH_path, 'omega')
   psi_path = os.path.join(ADH_path, 'psi')
@@ -989,7 +1026,7 @@ def verify_file_deleted(message, path):
   except IOError:
     return
   if message is not None:
-    print(message)
+    logger.warn(message)
   ###TODO We should raise a less generic error here. which?
   raise svntest.Failure
 
@@ -1007,22 +1044,22 @@ def basic_delete(sbox):
   wc_dir = sbox.wc_dir
 
   # modify text of chi
-  chi_parent_path = os.path.join(wc_dir, 'A', 'D', 'H')
+  chi_parent_path = sbox.ospath('A/D/H')
   chi_path = os.path.join(chi_parent_path, 'chi')
   svntest.main.file_append(chi_path, 'added to chi')
 
   # modify props of rho (file)
-  rho_parent_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  rho_parent_path = sbox.ospath('A/D/G')
   rho_path = os.path.join(rho_parent_path, 'rho')
   svntest.main.run_svn(None, 'ps', 'abc', 'def', rho_path)
 
   # modify props of F (dir)
-  F_parent_path = os.path.join(wc_dir, 'A', 'B')
+  F_parent_path = sbox.ospath('A/B')
   F_path = os.path.join(F_parent_path, 'F')
   svntest.main.run_svn(None, 'ps', 'abc', 'def', F_path)
 
   # unversioned file
-  sigma_parent_path = os.path.join(wc_dir, 'A', 'C')
+  sigma_parent_path = sbox.ospath('A/C')
   sigma_path = os.path.join(sigma_parent_path, 'sigma')
   svntest.main.file_append(sigma_path, 'unversioned sigma')
 
@@ -1032,13 +1069,13 @@ def basic_delete(sbox):
   os.mkdir(Q_path)
 
   # added directory hierarchies
-  X_parent_path =  os.path.join(wc_dir, 'A', 'B')
+  X_parent_path =  sbox.ospath('A/B')
   X_path = os.path.join(X_parent_path, 'X')
   svntest.main.run_svn(None, 'mkdir', X_path)
   X_child_path = os.path.join(X_path, 'xi')
   svntest.main.file_append(X_child_path, 'added xi')
   svntest.main.run_svn(None, 'add', X_child_path)
-  Y_parent_path = os.path.join(wc_dir, 'A', 'D')
+  Y_parent_path = sbox.ospath('A/D')
   Y_path = os.path.join(Y_parent_path, 'Y')
   svntest.main.run_svn(None, 'mkdir', Y_path)
 
@@ -1087,7 +1124,7 @@ def basic_delete(sbox):
   svntest.actions.run_and_verify_status(wc_dir, expected_output)
 
   # 'svn rm' that should work
-  E_path =  os.path.join(wc_dir, 'A', 'B', 'E')
+  E_path =  sbox.ospath('A/B/E')
   svntest.actions.run_and_verify_svn(None, None, [], 'rm', E_path)
 
   # 'svn rm --force' that should work
@@ -1107,13 +1144,13 @@ def basic_delete(sbox):
                                      'rm', '--force', X_path)
 
   # Deleting already removed from wc versioned item with --force
-  iota_path = os.path.join(wc_dir, 'iota')
+  iota_path = sbox.ospath('iota')
   os.remove(iota_path)
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'rm', '--force', iota_path)
 
   # and without --force
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
   os.remove(gamma_path)
   svntest.actions.run_and_verify_svn(None, None, [], 'rm', gamma_path)
 
@@ -1168,16 +1205,16 @@ def basic_delete(sbox):
 
   # check unversioned and added dirs has been removed
   if verify_dir_deleted(Q_path):
-    print("Failed to remove unversioned dir")
+    logger.warn("Failed to remove unversioned dir")
     ### we should raise a less generic error here. which?
     raise svntest.Failure
   if verify_dir_deleted(X_path):
-    print("Failed to remove added dir")
+    logger.warn("Failed to remove added dir")
     ### we should raise a less generic error here. which?
     raise svntest.Failure
 
   # Deleting unversioned file explicitly
-  foo_path = os.path.join(wc_dir, 'foo')
+  foo_path = sbox.ospath('foo')
   svntest.main.file_append(foo_path, 'unversioned foo')
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'rm', '--force', foo_path)
@@ -1206,7 +1243,7 @@ def basic_checkout_deleted(sbox):
   wc_dir = sbox.wc_dir
 
   # Delete A/D and commit.
-  D_path = os.path.join(wc_dir, 'A', 'D')
+  D_path = sbox.ospath('A/D')
   svntest.actions.run_and_verify_svn("error scheduling A/D for deletion",
                                      None, [], 'rm', '--force', D_path)
 
@@ -1225,7 +1262,7 @@ def basic_checkout_deleted(sbox):
 
   # Now try to checkout revision 1 of A/D.
   url = sbox.repo_url + '/A/D'
-  wc2 = os.path.join(sbox.wc_dir, 'new_D')
+  wc2 = sbox.ospath('new_D')
   svntest.actions.run_and_verify_svn("error checking out r1 of A/D",
                                      None, [], 'co', '-r', '1',
                                      url + "@1", wc2)
@@ -1242,7 +1279,7 @@ def basic_node_kind_change(sbox):
   wc_dir = sbox.wc_dir
 
   # Schedule a file for deletion
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
   svntest.main.run_svn(None, 'rm', gamma_path)
 
   # Status shows deleted file
@@ -1297,7 +1334,7 @@ def basic_import(sbox):
   wc_dir = sbox.wc_dir
 
   # create a new directory with files of various permissions
-  new_path = os.path.join(wc_dir, 'new_file')
+  new_path = sbox.ospath('new_file')
 
   svntest.main.file_append(new_path, "some text")
 
@@ -1355,7 +1392,7 @@ def basic_cat(sbox):
   sbox.build(read_only = True)
   wc_dir = sbox.wc_dir
 
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  mu_path = sbox.ospath('A/mu')
 
   # Get repository text even if wc is modified
   svntest.main.file_append(mu_path, "some text")
@@ -1391,22 +1428,22 @@ def basic_ls(sbox):
   svntest.actions.run_and_verify_svn('ls a working copy directory',
                                      ['B/\n', 'C/\n', 'D/\n', 'mu\n'],
                                      [], 'ls',
-                                     os.path.join(wc_dir, 'A'))
+                                     sbox.ospath('A'))
 
   svntest.actions.run_and_verify_svn('ls working copy directory with -r BASE',
                                      ['B/\n', 'C/\n', 'D/\n', 'mu\n'],
                                      [], 'ls', '-r', 'BASE',
-                                     os.path.join(wc_dir, 'A'))
+                                     sbox.ospath('A'))
 
   svntest.actions.run_and_verify_svn('ls a single file',
                                      ['mu\n'],
                                      [], 'ls',
-                                     os.path.join(wc_dir, 'A', 'mu'))
+                                     sbox.ospath('A/mu'))
 
   svntest.actions.run_and_verify_svn('recursive ls',
                                      ['E/\n', 'E/alpha\n', 'E/beta\n', 'F/\n',
                                       'lambda\n' ], [], 'ls', '-R',
-                                     os.path.join(wc_dir, 'A', 'B'))
+                                     sbox.ospath('A/B'))
 
 
 #----------------------------------------------------------------------
@@ -1472,16 +1509,16 @@ def basic_auth_cache(sbox):
                                      repo_url, wc_dir)
 
   # Failed with "not locked" error on missing directory
-  svntest.main.safe_rmtree(os.path.join(wc_dir, 'A', 'B', 'E'))
+  svntest.main.safe_rmtree(sbox.ospath('A/B/E'))
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'status', '-u',
-                                     os.path.join(wc_dir, 'A', 'B'))
+                                     sbox.ospath('A/B'))
 
   # Failed with "already locked" error on new dir
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'copy',
                                      repo_url + '/A/B/E',
-                                     os.path.join(wc_dir, 'A', 'D', 'G'))
+                                     sbox.ospath('A/D/G'))
 
 
 #----------------------------------------------------------------------
@@ -1498,7 +1535,7 @@ def basic_add_ignores(sbox):
   sbox.build(read_only = True)
   wc_dir = sbox.wc_dir
 
-  dir_path = os.path.join(wc_dir, 'dir')
+  dir_path = sbox.ospath('dir')
   foo_c_path = os.path.join(dir_path, 'foo.c')
   foo_o_path = os.path.join(dir_path, 'foo.o')
 
@@ -1528,7 +1565,7 @@ def basic_add_local_ignores(sbox):
   sbox.build(read_only = True)
   wc_dir = sbox.wc_dir
 
-  dir_path = os.path.join(wc_dir, 'dir')
+  dir_path = sbox.ospath('dir')
   file_path = os.path.join(dir_path, 'app.lock')
 
   svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
@@ -1546,7 +1583,7 @@ def basic_add_no_ignores(sbox):
   sbox.build(read_only = True)
   wc_dir = sbox.wc_dir
 
-  dir_path = os.path.join(wc_dir, 'dir')
+  dir_path = sbox.ospath('dir')
   foo_c_path = os.path.join(dir_path, 'foo.c')
   # add a few files that match the default ignore patterns
   foo_o_path = os.path.join(dir_path, 'foo.o')
@@ -1575,7 +1612,7 @@ def basic_add_parents(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  X_path = os.path.join(wc_dir, 'X')
+  X_path = sbox.ospath('X')
   Y_path = os.path.join(X_path, 'Y')
   Z_path = os.path.join(Y_path, 'Z')
   zeta_path = os.path.join(Z_path, 'zeta')
@@ -1673,8 +1710,8 @@ def basic_info(sbox):
       if line.startswith('Path: '):
         paths.append(line[6:].rstrip())
     if paths != expected_paths:
-      print("Reported paths: %s" % paths)
-      print("Expected paths: %s" % expected_paths)
+      logger.warn("Reported paths: %s" % paths)
+      logger.warn("Expected paths: %s" % expected_paths)
       raise svntest.Failure
 
   sbox.build(read_only = True)
@@ -1697,7 +1734,7 @@ def repos_root(sbox):
       if line == "Repository Root: " + sbox.repo_url + "\n":
         break
     else:
-      print("Bad or missing repository root")
+      logger.warn("Bad or missing repository root")
       raise svntest.Failure
 
   sbox.build(read_only = True)
@@ -1776,7 +1813,7 @@ def info_nonhead(sbox):
 
   wc_dir = sbox.wc_dir
   repo_url = sbox.repo_url
-  fname = os.path.join(wc_dir, 'iota')
+  fname = sbox.ospath('iota')
   furl = repo_url + "/iota"
 
   # Remove iota and commit.
@@ -1809,7 +1846,7 @@ def ls_nonhead(sbox):
   wc_dir = sbox.wc_dir
 
   # Delete A/D/rho and commit.
-  G_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  G_path = sbox.ospath('A/D/G')
   svntest.actions.run_and_verify_svn("error scheduling A/D/G for deletion",
                                      None, [], 'rm', G_path)
 
@@ -1838,7 +1875,7 @@ def cat_added_PREV(sbox):
 
   sbox.build(read_only = True)
   wc_dir = sbox.wc_dir
-  f_path = os.path.join(wc_dir, 'f')
+  f_path = sbox.ospath('f')
 
   # Create and add a file.
   svntest.main.file_append(f_path, 'new text')
@@ -1869,8 +1906,8 @@ def delete_keep_local(sbox):
 
   sbox.build()
   wc_dir = sbox.wc_dir
-  iota_path = os.path.join(wc_dir, 'iota')
-  C_path = os.path.join(wc_dir, 'A', 'C')
+  iota_path = sbox.ospath('iota')
+  C_path = sbox.ospath('A/C')
 
   # Remove file iota
   svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--keep-local',
@@ -1912,7 +1949,7 @@ def delete_keep_local_twice(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  dir = os.path.join(wc_dir, 'dir')
+  dir = sbox.ospath('dir')
 
   svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', dir)
 
@@ -1920,7 +1957,7 @@ def delete_keep_local_twice(sbox):
   svntest.actions.run_and_verify_svn(None, None, [], 'rm', '--keep-local', dir)
 
   if not os.path.isdir(dir):
-    print('Directory was really deleted')
+    logger.warn('Directory was really deleted')
     raise svntest.Failure
 
 def windows_paths_in_repos(sbox):
@@ -2064,11 +2101,11 @@ def automatic_conflict_resolution(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_backup)
 
   # Make a couple of local mods to files which will be committed
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
-  tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
+  mu_path = sbox.ospath('A/mu')
+  lambda_path = sbox.ospath('A/B/lambda')
+  rho_path = sbox.ospath('A/D/G/rho')
+  tau_path = sbox.ospath('A/D/G/tau')
+  omega_path = sbox.ospath('A/D/H/omega')
   svntest.main.file_append(mu_path, 'Original appended text for mu\n')
   svntest.main.file_append(lambda_path, 'Original appended text for lambda\n')
   svntest.main.file_append(rho_path, 'Original appended text for rho\n')
@@ -2194,8 +2231,8 @@ def automatic_conflict_resolution(sbox):
     # probably reveal the cause for the failure, if they were
     # uncommented:
     #
-    # print("Not all extra reject files have been accounted for:")
-    # print(extra_files)
+    # logger.warn("Not all extra reject files have been accounted for:")
+    # logger.warn(extra_files)
     ### we should raise a less generic error here. which?
     raise svntest.Failure
 
@@ -2317,7 +2354,7 @@ def basic_relative_url_using_current_dir
   sbox.build()
 
   # First, make a new revision of iota.
-  iota = os.path.join(sbox.wc_dir, 'iota')
+  iota = sbox.ospath('iota')
   svntest.main.file_append(iota, "New contents for iota\n")
   svntest.main.run_svn(None, 'ci',
                        '-m', '', iota)
@@ -2342,13 +2379,13 @@ def basic_relative_url_using_other_targe
   sbox.build()
 
   # First, make a new revision of iota.
-  iota = os.path.join(sbox.wc_dir, 'iota')
+  iota = sbox.ospath('iota')
   svntest.main.file_append(iota, "New contents for iota\n")
   svntest.main.run_svn(None, 'ci',
                        '-m', '', iota)
 
   # Now, make a new revision of A/mu .
-  mu = os.path.join(sbox.wc_dir, 'A', 'mu')
+  mu = sbox.ospath('A/mu')
   mu_url = sbox.repo_url + '/A/mu'
 
   svntest.main.file_append(mu, "New contents for mu\n")
@@ -2420,7 +2457,7 @@ def basic_relative_url_with_peg_revision
   sbox.build()
 
   # First, make a new revision of iota.
-  iota = os.path.join(sbox.wc_dir, 'iota')
+  iota = sbox.ospath('iota')
   svntest.main.file_append(iota, "New contents for iota\n")
   svntest.main.run_svn(None, 'ci',
                        '-m', '', iota)
@@ -2428,7 +2465,7 @@ def basic_relative_url_with_peg_revision
   iota_url = sbox.repo_url + '/iota'
 
   # Now, make a new revision of A/mu .
-  mu = os.path.join(sbox.wc_dir, 'A', 'mu')
+  mu = sbox.ospath('A/mu')
   mu_url = sbox.repo_url + '/A/mu'
 
   svntest.main.file_append(mu, "New contents for mu\n")
@@ -2563,8 +2600,8 @@ def delete_and_add_same_file(sbox):
 
   wc_dir = sbox.wc_dir
 
-  iota = os.path.join(wc_dir, 'iota')
-  iota2 = os.path.join(wc_dir, 'iota2')
+  iota = sbox.ospath('iota')
+  iota2 = sbox.ospath('iota2')
 
   shutil.copyfile(iota, iota2)
 
@@ -2725,7 +2762,7 @@ def ls_multiple_and_non_existent_targets
 
   def non_existent_wc_target():
     "non-existent wc target"
-    non_existent_path = os.path.join(wc_dir, 'non-existent')
+    non_existent_path = sbox.ospath('non-existent')
 
     expected_err = ".*W155010.*"
     svntest.actions.run_and_verify_svn2(None, None, expected_err,
@@ -2743,7 +2780,7 @@ def ls_multiple_and_non_existent_targets
 
     alpha = sbox.ospath('A/B/E/alpha')
     beta = sbox.ospath('A/B/E/beta')
-    non_existent_path = os.path.join(wc_dir, 'non-existent')
+    non_existent_path = sbox.ospath('non-existent')
 
     # All targets are existing
     svntest.actions.run_and_verify_svn2(None, None, [],
@@ -2797,7 +2834,7 @@ def add_multiple_targets(sbox):
 
   file1 = sbox.ospath('file1')
   file2 = sbox.ospath('file2')
-  non_existent_path = os.path.join(wc_dir, 'non-existent')
+  non_existent_path = sbox.ospath('non-existent')
 
   svntest.main.file_write(file1, "file1 contents", 'w+')
   svntest.main.file_write(file2, "file2 contents", 'w+')
@@ -2896,8 +2933,8 @@ def rm_missing_with_case_clashing_ondisk
   sbox.build(read_only = True)
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  IOTA_path = os.path.join(wc_dir, 'IOTA')
+  iota_path = sbox.ospath('iota')
+  IOTA_path = sbox.ospath('IOTA')
 
   # Out-of-svn move, to make iota missing, while IOTA appears as unversioned.
   os.rename(iota_path, IOTA_path)
@@ -2958,7 +2995,8 @@ test_list = [ None,
               basic_mkdir_url,
               basic_mkdir_url_with_parents,
               basic_mkdir_wc_with_parents,
-              basic_corruption,
+              basic_commit_corruption,
+              basic_update_corruption,
               basic_merging_update,
               basic_conflict,
               basic_cleanup,

Modified: subversion/branches/fix-rdump-editor/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/subversion/tests/cmdline/commit_tests.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/fix-rdump-editor/subversion/tests/cmdline/commit_tests.py Wed May 16 20:32:43 2012
@@ -160,7 +160,7 @@ def commit_one_file(sbox):
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
+  omega_path = sbox.ospath('A/D/H/omega')
 
   # Create expected state.
   expected_output = svntest.wc.State(wc_dir, {
@@ -186,7 +186,7 @@ def commit_one_new_file(sbox):
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
+  gloo_path = sbox.ospath('A/D/H/gloo')
 
   # Create expected state.
   expected_output = svntest.wc.State(wc_dir, {
@@ -212,7 +212,7 @@ def commit_one_new_binary_file(sbox):
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
+  gloo_path = sbox.ospath('A/D/H/gloo')
   svntest.main.run_svn(None, 'propset', 'svn:mime-type',
                        'application/octet-stream', gloo_path)
 
@@ -241,12 +241,12 @@ def commit_multiple_targets(sbox):
   # This test will commit three targets:  psi, B, and pi.  In that order.
 
   # Make local mods to many files.
-  AB_path = os.path.join(wc_dir, 'A', 'B')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
-  psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
+  AB_path = sbox.ospath('A/B')
+  lambda_path = sbox.ospath('A/B/lambda')
+  rho_path = sbox.ospath('A/D/G/rho')
+  pi_path = sbox.ospath('A/D/G/pi')
+  omega_path = sbox.ospath('A/D/H/omega')
+  psi_path = sbox.ospath('A/D/H/psi')
   svntest.main.file_append(lambda_path, 'new appended text for lambda')
   svntest.main.file_append(rho_path, 'new appended text for rho')
   svntest.main.file_append(pi_path, 'new appended text for pi')
@@ -255,7 +255,7 @@ def commit_multiple_targets(sbox):
 
   # Just for kicks, add a property to A/D/G as well.  We'll make sure
   # that it *doesn't* get committed.
-  ADG_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  ADG_path = sbox.ospath('A/D/G')
   svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path)
 
   # Create expected output tree for 'svn ci'.  We should see changes
@@ -295,12 +295,12 @@ def commit_multiple_targets_2(sbox):
   # This test will commit four targets:  psi, B, omega and pi.  In that order.
 
   # Make local mods to many files.
-  AB_path = os.path.join(wc_dir, 'A', 'B')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
-  psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
+  AB_path = sbox.ospath('A/B')
+  lambda_path = sbox.ospath('A/B/lambda')
+  rho_path = sbox.ospath('A/D/G/rho')
+  pi_path = sbox.ospath('A/D/G/pi')
+  omega_path = sbox.ospath('A/D/H/omega')
+  psi_path = sbox.ospath('A/D/H/psi')
   svntest.main.file_append(lambda_path, 'new appended text for lambda')
   svntest.main.file_append(rho_path, 'new appended text for rho')
   svntest.main.file_append(pi_path, 'new appended text for pi')
@@ -309,7 +309,7 @@ def commit_multiple_targets_2(sbox):
 
   # Just for kicks, add a property to A/D/G as well.  We'll make sure
   # that it *doesn't* get committed.
-  ADG_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  ADG_path = sbox.ospath('A/D/G')
   svntest.main.run_svn(None, 'propset', 'foo', 'bar', ADG_path)
 
   # Created expected output tree for 'svn ci'.  We should see changes
@@ -350,7 +350,7 @@ def commit_inclusive_dir(sbox):
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  D_path = os.path.join(wc_dir, 'A', 'D')
+  D_path = sbox.ospath('A/D')
 
   # Create expected state.
   expected_output = svntest.wc.State(wc_dir, {
@@ -440,7 +440,7 @@ def commit_unversioned_thing(sbox):
   wc_dir = sbox.wc_dir
 
   # Create an unversioned file in the wc.
-  svntest.main.file_append(os.path.join(wc_dir, 'blorg'), "nothing to see")
+  svntest.main.file_append(sbox.ospath('blorg'), "nothing to see")
 
   # Commit a non-existent file and *expect* failure:
   svntest.actions.run_and_verify_commit(wc_dir,
@@ -459,7 +459,7 @@ def nested_dir_replacements(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  A_D = os.path.join(wc_dir, 'A', 'D')
+  A_D = sbox.ospath('A/D')
 
   # Delete and re-add A/D (a replacement), and A/D/H (another replace).
   svntest.main.run_svn(None, 'rm', A_D)
@@ -542,7 +542,7 @@ def hudson_part_1(sbox):
   wc_dir = sbox.wc_dir
 
   # Remove gamma from the working copy.
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
   svntest.main.run_svn(None, 'rm', gamma_path)
 
   # Create expected commit output.
@@ -593,7 +593,7 @@ def hudson_part_1_variation_1(sbox):
   wc_dir = sbox.wc_dir
 
   # Remove H from the working copy.
-  H_path = os.path.join(wc_dir, 'A', 'D', 'H')
+  H_path = sbox.ospath('A/D/H')
   svntest.main.run_svn(None, 'rm', H_path)
 
   # Create expected commit output.
@@ -644,7 +644,7 @@ def hudson_part_1_variation_2(sbox):
   wc_dir = sbox.wc_dir
 
   # Remove gamma from the working copy.
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
   svntest.main.run_svn(None, 'rm', gamma_path)
 
   # Create expected commit output.
@@ -703,8 +703,8 @@ def hudson_part_2(sbox):
   wc_dir = sbox.wc_dir
 
   # Remove gamma from the working copy.
-  D_path = os.path.join(wc_dir, 'A', 'D')
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  D_path = sbox.ospath('A/D')
+  gamma_path = sbox.ospath('A/D/gamma')
   svntest.main.run_svn(None, 'rm', gamma_path)
 
   # Create expected commit output.
@@ -751,8 +751,8 @@ def hudson_part_2_1(sbox):
   wc_dir = sbox.wc_dir
 
   # Move all the files in H to G
-  H_path = os.path.join(wc_dir, 'A', 'D', 'H')
-  G_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  H_path = sbox.ospath('A/D/H')
+  G_path = sbox.ospath('A/D/G')
   chi_path = os.path.join(H_path, 'chi')
   psi_path = os.path.join(H_path, 'psi')
   omega_path = os.path.join(H_path, 'omega')
@@ -842,7 +842,7 @@ fp.close()"""
                                          hook_format % "post_commit_hook")
 
   # Modify iota just so there is something to commit.
-  iota_path = os.path.join(wc_dir, "iota")
+  iota_path = sbox.ospath('iota')
   svntest.main.file_append(iota_path, "More stuff in iota")
 
   # Commit, no output expected.
@@ -880,10 +880,10 @@ def merge_mixed_revisions(sbox):
   wc_dir = sbox.wc_dir
 
   # Make some convenient paths.
-  iota_path = os.path.join(wc_dir, 'iota')
-  H_path = os.path.join(wc_dir, 'A', 'D', 'H')
-  chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
+  iota_path = sbox.ospath('iota')
+  H_path = sbox.ospath('A/D/H')
+  chi_path = sbox.ospath('A/D/H/chi')
+  omega_path = sbox.ospath('A/D/H/omega')
 
   # Here's the reproduction formula, in 5 parts.
   # Hoo, what a buildup of state!
@@ -1029,15 +1029,15 @@ def commit_uri_unsafe(sbox):
     nasty_name = '#![]{}()<>%'
 
   # Make some convenient paths.
-  hash_dir = os.path.join(wc_dir, '#hash#')
+  hash_dir = sbox.ospath('#hash#')
   nasty_dir = os.path.join(wc_dir, nasty_name)
-  space_path = os.path.join(wc_dir, 'A', 'D', 'space path')
-  bang_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bang!')
-  bracket_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra[ket')
-  brace_path = os.path.join(wc_dir, 'A', 'D', 'H', 'bra{e')
+  space_path = sbox.ospath('A/D/space path')
+  bang_path = sbox.ospath('A/D/H/bang!')
+  bracket_path = sbox.ospath('A/D/H/bra[ket')
+  brace_path = sbox.ospath('A/D/H/bra{e')
   angle_path = os.path.join(wc_dir, 'A', 'D', 'H', angle_name)
-  paren_path = os.path.join(wc_dir, 'A', 'D', 'pare)(theses')
-  percent_path = os.path.join(wc_dir, '#hash#', 'percen%')
+  paren_path = sbox.ospath('A/D/pare)(theses')
+  percent_path = sbox.ospath('#hash#/percen%')
   nasty_path = os.path.join(wc_dir, 'A', nasty_name)
 
   os.mkdir(hash_dir)
@@ -1099,8 +1099,8 @@ def commit_deleted_edited(sbox):
   wc_dir = sbox.wc_dir
 
   # Make some convenient paths.
-  iota_path = os.path.join(wc_dir, 'iota')
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  iota_path = sbox.ospath('iota')
+  mu_path = sbox.ospath('A/mu')
 
   # Edit the files.
   svntest.main.file_append(iota_path, "This file has been edited.")
@@ -1134,10 +1134,10 @@ def commit_in_dir_scheduled_for_addition
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  A_path = os.path.join(wc_dir, 'A')
-  Z_path = os.path.join(wc_dir, 'Z')
+  A_path = sbox.ospath('A')
+  Z_path = sbox.ospath('Z')
   Z_abspath = os.path.abspath(Z_path)
-  mu_path = os.path.join(wc_dir, 'Z', 'mu')
+  mu_path = sbox.ospath('Z/mu')
 
   svntest.main.run_svn(None, 'move', A_path, Z_path)
 
@@ -1154,7 +1154,7 @@ def commit_in_dir_scheduled_for_addition
                                         "' is not known to exist in the",
                                         mu_path)
 
-  Q_path = os.path.join(wc_dir, 'Q')
+  Q_path = sbox.ospath('Q')
   Q_abspath = os.path.abspath(Q_path)
   bloo_path = os.path.join(Q_path, 'bloo')
 
@@ -1193,7 +1193,7 @@ def commit_rmd_and_deleted_file(sbox):
 
   sbox.build()
   wc_dir = sbox.wc_dir
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  mu_path = sbox.ospath('A/mu')
 
   # 'svn remove' mu
   svntest.main.run_svn(None, 'rm', mu_path)
@@ -1214,7 +1214,7 @@ def commit_add_file_twice(sbox):
   wc_dir = sbox.wc_dir
 
   # Create a file
-  gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
+  gloo_path = sbox.ospath('A/D/H/gloo')
   svntest.main.file_append(gloo_path, "hello")
   svntest.main.run_svn(None, 'add', gloo_path)
 
@@ -1266,7 +1266,7 @@ def commit_from_long_dir(sbox):
   abs_wc_dir = os.path.realpath(os.path.join(was_dir, wc_dir))
 
   # something to commit
-  svntest.main.file_append(os.path.join(wc_dir, 'iota'), "modified iota")
+  svntest.main.file_append(sbox.ospath('iota'), "modified iota")
 
   # Create expected output tree.
   expected_output = svntest.wc.State('', {
@@ -1297,7 +1297,7 @@ def commit_with_lock(sbox):
   # modify gamma and lock its directory
   wc_dir = sbox.wc_dir
 
-  D_path = os.path.join(wc_dir, 'A', 'D')
+  D_path = sbox.ospath('A/D')
   gamma_path = os.path.join(D_path, 'gamma')
   svntest.main.file_append(gamma_path, "modified gamma")
   svntest.actions.lock_admin_dir(D_path)
@@ -1375,7 +1375,7 @@ def failed_commit(sbox):
   svntest.actions.duplicate_dir(wc_dir, other_wc_dir)
 
   # Make different changes in the two working copies
-  iota_path = os.path.join(wc_dir, "iota")
+  iota_path = sbox.ospath('iota')
   svntest.main.file_append(iota_path, "More stuff in iota")
 
   other_iota_path = os.path.join(other_wc_dir, "iota")
@@ -1414,7 +1414,7 @@ def commit_multiple_wc_nested(sbox):
   wc_dir = sbox.wc_dir
 
   # Checkout a second working copy
-  wc2_dir = os.path.join(wc_dir, 'A', 'wc2')
+  wc2_dir = sbox.ospath('A/wc2')
   url = sbox.repo_url
   svntest.actions.run_and_verify_svn("Output on stderr where none expected",
                                      svntest.verify.AnyOutput, [],
@@ -1422,7 +1422,7 @@ def commit_multiple_wc_nested(sbox):
                                      url, wc2_dir)
 
   # Modify both working copies
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  mu_path = sbox.ospath('A/mu')
   svntest.main.file_append(mu_path, 'appended mu text')
   lambda2_path = os.path.join(wc2_dir, 'A', 'B', 'lambda')
   svntest.main.file_append(lambda2_path, 'appended lambda2 text')
@@ -1459,8 +1459,8 @@ def commit_multiple_wc(sbox):
   svntest.sandbox._cleanup_test_path(wc_dir)
 
   # Checkout two wcs
-  wc1_dir = os.path.join(wc_dir, 'wc1')
-  wc2_dir = os.path.join(wc_dir, 'wc2')
+  wc1_dir = sbox.ospath('wc1')
+  wc2_dir = sbox.ospath('wc2')
   url = sbox.repo_url
   svntest.actions.run_and_verify_svn("Output on stderr where none expected",
                                      svntest.verify.AnyOutput, [],
@@ -1515,8 +1515,8 @@ def commit_multiple_wc_multiple_repos(sb
   svntest.sandbox._cleanup_test_path(wc_dir)
 
   # Checkout two wcs
-  wc1_dir = os.path.join(wc_dir, 'wc1')
-  wc2_dir = os.path.join(wc_dir, 'wc2')
+  wc1_dir = sbox.ospath('wc1')
+  wc2_dir = sbox.ospath('wc2')
   svntest.actions.run_and_verify_svn("Output on stderr where none expected",
                                      svntest.verify.AnyOutput, [],
                                      'checkout',
@@ -1791,7 +1791,7 @@ def commit_out_of_date_deletions(sbox):
   wc_dir = sbox.wc_dir
 
   # Need another empty dir
-  I_path = os.path.join(wc_dir, 'A', 'I')
+  I_path = sbox.ospath('A/I')
   os.mkdir(I_path)
   svntest.main.run_svn(None, 'add', I_path)
   svntest.main.run_svn(None, 'ci', '-m', 'prep', wc_dir)
@@ -1802,19 +1802,19 @@ def commit_out_of_date_deletions(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_backup)
 
   # Edits in wc 1
-  C_path = os.path.join(wc_dir, 'A', 'C')
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
-  alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
+  C_path = sbox.ospath('A/C')
+  omega_path = sbox.ospath('A/D/H/omega')
+  alpha_path = sbox.ospath('A/B/E/alpha')
   svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', C_path)
   svntest.main.file_append(omega_path, 'appended omega text')
   svntest.main.run_svn(None, 'propset', 'fooprop', 'foopropval', alpha_path)
 
   # Deletions in wc 1
-  I_path = os.path.join(wc_dir, 'A', 'I')
-  F_path = os.path.join(wc_dir, 'A', 'B', 'F')
-  chi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'chi')
-  beta_path = os.path.join(wc_dir, 'A', 'B', 'E', 'beta')
-  psi_path = os.path.join(wc_dir, 'A', 'D', 'H', 'psi')
+  I_path = sbox.ospath('A/I')
+  F_path = sbox.ospath('A/B/F')
+  chi_path = sbox.ospath('A/D/H/chi')
+  beta_path = sbox.ospath('A/B/E/beta')
+  psi_path = sbox.ospath('A/D/H/psi')
   svntest.main.run_svn(None, 'rm', I_path, F_path, chi_path, beta_path,
                        psi_path)
 
@@ -1871,8 +1871,8 @@ def commit_with_bad_log_message(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  log_msg_path = os.path.join(wc_dir, 'log-message')
+  iota_path = sbox.ospath('iota')
+  log_msg_path = sbox.ospath('log-message')
 
   # Make a random change, so there's something to commit.
   svntest.main.file_append(iota_path, 'fish')
@@ -1895,8 +1895,8 @@ def commit_with_mixed_line_endings(sbox)
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  log_msg_path = os.path.join(wc_dir, 'log-message')
+  iota_path = sbox.ospath('iota')
+  log_msg_path = sbox.ospath('log-message')
 
   # Make a random change, so there's something to commit.
   svntest.main.file_append(iota_path, 'kebab')
@@ -1919,8 +1919,8 @@ def commit_with_mixed_line_endings_in_ig
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  log_msg_path = os.path.join(wc_dir, 'log-message')
+  iota_path = sbox.ospath('iota')
+  log_msg_path = sbox.ospath('log-message')
 
   # Make a random change, so there's something to commit.
   svntest.main.file_append(iota_path, 'cheeseburger')
@@ -1990,7 +1990,7 @@ def mods_in_schedule_delete(sbox):
   wc_dir = sbox.wc_dir
 
   # Schedule a delete, then put in local mods
-  C_path = os.path.join(wc_dir, 'A', 'C')
+  C_path = sbox.ospath('A/C')
   svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
                                      'rm', C_path)
 
@@ -2026,8 +2026,8 @@ def tab_test(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  tab_file = os.path.join(wc_dir, 'A', "tab\tfile")
-  tab_dir  = os.path.join(wc_dir, 'A', "tab\tdir")
+  tab_file = sbox.ospath('A/tab\tfile')
+  tab_dir  = sbox.ospath('A/tab\tdir')
   source_url = sbox.repo_url + "/source_dir"
   tab_url = sbox.repo_url + "/tab%09dir"
 
@@ -2091,30 +2091,30 @@ def local_mods_are_not_commits(sbox):
   # copy wc->wc
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'cp', '-m', 'log msg',
-                                     os.path.join(wc_dir, 'iota'),
-                                     os.path.join(wc_dir, 'iota2'))
+                                     sbox.ospath('iota'),
+                                     sbox.ospath('iota2'))
 
   # copy repos->wc
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'cp', '-m', 'log msg',
                                      sbox.repo_url + "/iota",
-                                     os.path.join(wc_dir, 'iota2'))
+                                     sbox.ospath('iota2'))
 
   # delete
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'rm', '-m', 'log msg',
-                                     os.path.join(wc_dir, 'A', 'D', 'gamma'))
+                                     sbox.ospath('A/D/gamma'))
 
   # mkdir
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'mkdir', '-m', 'log msg',
-                                     os.path.join(wc_dir, 'newdir'))
+                                     sbox.ospath('newdir'))
 
   # rename
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'cp', '-m', 'log msg',
-                                     os.path.join(wc_dir, 'A', 'mu'),
-                                     os.path.join(wc_dir, 'A', 'yu'))
+                                     sbox.ospath('A/mu'),
+                                     sbox.ospath('A/yu'))
 
 
 #----------------------------------------------------------------------
@@ -2136,7 +2136,7 @@ def post_commit_hook_test(sbox):
   svntest.actions.create_failing_hook(repo_dir, "post-commit", error_msg)
 
   # Modify iota just so there is something to commit.
-  iota_path = os.path.join(wc_dir, "iota")
+  iota_path = sbox.ospath('iota')
   svntest.main.file_append(iota_path, "lakalakalakalaka")
 
   # Now, commit and examine the output (we happen to know that the
@@ -2163,7 +2163,7 @@ def commit_same_folder_in_targets(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
+  iota_path = sbox.ospath('iota')
 
   svntest.main.file_append(iota_path, "added extra line to file iota")
 
@@ -2196,8 +2196,8 @@ def commit_inconsistent_eol(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  iota_path = sbox.ospath('iota')
+  mu_path = sbox.ospath('A/mu')
 
   svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', iota_path)
   svntest.main.file_append_binary(iota_path,
@@ -2263,8 +2263,8 @@ def commit_with_revprop(sbox):
   wc_dir = sbox.wc_dir
   expected_status = make_standard_slew_of_changes(wc_dir)
 
-  omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
-  gloo_path = os.path.join(wc_dir, 'A', 'D', 'H', 'gloo')
+  omega_path = sbox.ospath('A/D/H/omega')
+  gloo_path = sbox.ospath('A/D/H/gloo')
   expected_output = svntest.wc.State(wc_dir, {
     'A/D/H/omega' : Item(verb='Sending'),
     'A/D/H/gloo' : Item(verb='Adding'),
@@ -2296,8 +2296,8 @@ def import_with_revprop(sbox):
   "set revision props during import"
 
   sbox.build()
-  local_dir = os.path.join(sbox.wc_dir, 'folder')
-  local_file = os.path.join(sbox.wc_dir, 'folder', 'file')
+  local_dir = sbox.ospath('folder')
+  local_file = sbox.ospath('folder/file')
   os.mkdir(local_dir)
   svntest.main.file_write(local_file, "xxxx")
 
@@ -2345,7 +2345,7 @@ def copy_WC2R_with_revprop(sbox):
 
   sbox.build()
   remote_dir = sbox.repo_url + "/dir"
-  local_dir = os.path.join(sbox.wc_dir, 'folder')
+  local_dir = sbox.ospath('folder')
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'mkdir', local_dir)
 
@@ -2518,7 +2518,7 @@ def start_commit_hook_test(sbox):
   svntest.actions.create_failing_hook(repo_dir, "start-commit", error_msg)
 
   # Modify iota just so there is something to commit.
-  iota_path = os.path.join(wc_dir, "iota")
+  iota_path = sbox.ospath('iota')
   svntest.main.file_append(iota_path, "More stuff in iota")
 
   # Commit, expect error code 1
@@ -2558,7 +2558,7 @@ def pre_commit_hook_test(sbox):
   svntest.actions.create_failing_hook(repo_dir, "pre-commit", error_msg)
 
   # Modify iota just so there is something to commit.
-  iota_path = os.path.join(wc_dir, "iota")
+  iota_path = sbox.ospath('iota')
   svntest.main.file_append(iota_path, "More stuff in iota")
 
   # Commit, expect error code 1
@@ -2624,9 +2624,9 @@ def changelist_near_conflict(sbox):
   sbox.build()
 
   wc_dir = sbox.wc_dir
-  iota_path = os.path.join(wc_dir, "iota")
-  mu_path = os.path.join(wc_dir, "A", "mu")
-  gloo_path = os.path.join(wc_dir, "A", "D", "H", "gloo")
+  iota_path = sbox.ospath('iota')
+  mu_path = sbox.ospath('A/mu')
+  gloo_path = sbox.ospath('A/D/H/gloo')
 
   expected_status = make_standard_slew_of_changes(wc_dir)
 
@@ -2665,7 +2665,7 @@ def commit_out_of_date_file(sbox):
   wc_backup = sbox.add_wc_path('backup')
   svntest.actions.duplicate_dir(wc_dir, wc_backup)
 
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
+  pi_path = sbox.ospath('A/D/G/pi')
   backup_pi_path = os.path.join(wc_backup, 'A', 'D', 'G', 'pi')
 
   svntest.main.file_append(pi_path, "new line\n")
@@ -2708,7 +2708,7 @@ def start_commit_detect_capabilities(sbo
   svntest.main.create_python_hook_script(start_commit_hook, hook_text)
 
   # Commit something.
-  iota_path = os.path.join(wc_dir, "iota")
+  iota_path = sbox.ospath('iota')
   svntest.main.file_append(iota_path, "More stuff in iota")
   svntest.actions.run_and_verify_svn(None, [], [], 'ci', '--quiet',
                                      '-m', 'log msg', wc_dir)
@@ -2730,9 +2730,9 @@ def commit_added_missing(sbox):
 
   sbox.build()
   wc_dir = sbox.wc_dir
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  a_path = os.path.join(wc_dir, 'A', 'a.txt')
-  b_path = os.path.join(wc_dir, 'A', 'b.txt')
+  mu_path = sbox.ospath('A/mu')
+  a_path = sbox.ospath('A/a.txt')
+  b_path = sbox.ospath('A/b.txt')
 
   # Make two copies of mu: a and b
   svntest.main.run_svn(None, 'cp', mu_path, a_path)
@@ -2765,9 +2765,9 @@ def tree_conflicts_block_commit(sbox):
 
   svntest.actions.build_greek_tree_conflicts(sbox)
   wc_dir = sbox.wc_dir
-  A = os.path.join(wc_dir, 'A')
-  D = os.path.join(wc_dir, 'A', 'D')
-  G = os.path.join(wc_dir, 'A', 'D', 'G')
+  A = sbox.ospath('A')
+  D = sbox.ospath('A/D')
+  G = sbox.ospath('A/D/G')
 
   error_re = "remains in conflict"
   commit_fails_at_path(wc_dir, wc_dir, error_re)
@@ -2792,7 +2792,7 @@ def tree_conflicts_resolved(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_dir_2)
 
   # Mark the tree conflict victims as resolved
-  G = os.path.join(wc_dir, 'A', 'D', 'G')
+  G = sbox.ospath('A/D/G')
   victims = [ os.path.join(G, v) for v in ['pi', 'rho', 'tau'] ]
   svntest.actions.run_and_verify_resolved(victims)
 
@@ -2818,7 +2818,7 @@ def commit_multiple_nested_deletes(sbox)
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  A = os.path.join(wc_dir, 'A')
+  A = sbox.ospath('A')
   A_B = os.path.join(A, 'B')
 
   sbox.simple_rm('A')
@@ -2877,6 +2877,44 @@ def commit_add_subadd(sbox):
   svntest.main.run_svn(None, 'merge', '-c', '-2', './')
   svntest.main.run_svn(None, 'commit', '--targets', targets_file, '-mm')
 
+def commit_danglers(sbox):
+  "verify committing some dangling children fails"
+
+  sbox.build(read_only=True)
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_copy('A','A_copied')
+
+  A_copied = sbox.ospath('A_copied')
+  mu_copied = sbox.ospath('A_copied/mu')
+
+  svntest.main.file_write(mu_copied, "xxxx")  
+
+  # We already test for this problem for some time
+  expected_error = "svn: E200009: '.*A_copied' .*exist.*yet.* '.*mu'.*part"
+  svntest.actions.run_and_verify_commit(mu_copied,
+                                        None,
+                                        None,
+                                        expected_error,
+                                        mu_copied)
+
+  # But now do the same thing via changelist filtering
+  svntest.main.run_svn(None, 'changelist', 'L', mu_copied, sbox.ospath('A/mu'))
+
+  # And try to commit A_copied itself with changelist filtering
+  svntest.actions.run_and_verify_commit(A_copied,
+                                        None,
+                                        None,
+                                        expected_error,
+                                        A_copied, '--cl', 'L')
+
+  # And on the wcroot
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        None,
+                                        None,
+                                        expected_error,
+                                        wc_dir, '--cl', 'L')
+
 
 ########################################################################
 # Run the tests
@@ -2947,6 +2985,7 @@ test_list = [ None,
               commit_multiple_nested_deletes,
               commit_incomplete,
               commit_add_subadd,
+              commit_danglers,
              ]
 
 if __name__ == '__main__':