You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/06/27 13:39:17 UTC

svn commit: r1497310 - in /subversion/trunk/subversion: include/svn_client.h libsvn_client/cleanup.c svn/cleanup-cmd.c svn/svn.c tests/cmdline/wc_tests.py

Author: stsp
Date: Thu Jun 27 11:39:17 2013
New Revision: 1497310

URL: http://svn.apache.org/r1497310
Log:
Forbid 'svn cleanup --remove-unversioned --remove-ignored' if the working
copy is already write-locked. This prevents accidental working copy
corruption in case users routinely run 'svn cleanup' with either of
these options while other Subversion clients are using the working copy.

Also, update and extend the help text of svn cleanup. The previous help text
failed to properly warn users of potentially bad consequences when running
'svn cleanup' in parallel with other operations on the same working copy,
and failed to explain what kind of locks are being removed.

* subversion/include/svn_client.h
  (svn_client_cleanup2): Extend docstring.

* subversion/libsvn_client/cleanup.c
  (svn_client_cleanup2): If asked to remove unversioned or ignored items,
   ensure that the working copy is not already locked via another WC context
   before running any cleanup actions that steal write locks.

* subversion/svn/cleanup-cmd.c
  (svn_cl__cleanup): Provide a reasonable error message if users try to
   remove unversioned or ignored items from a locked working copy.

* subversion/svn/svn.c
  (svn_cl__cmd_table): Update and extend 'svn cleanup' help text.

* subversion/tests/cmdline/wc_tests.py
  (cleanup_unversioned_items_in_locked_wc, test_list): New test.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/libsvn_client/cleanup.c
    subversion/trunk/subversion/svn/cleanup-cmd.c
    subversion/trunk/subversion/svn/svn.c
    subversion/trunk/subversion/tests/cmdline/wc_tests.py

Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1497310&r1=1497309&r2=1497310&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Thu Jun 27 11:39:17 2013
@@ -4030,6 +4030,12 @@ svn_client_mergeinfo_log_eligible(const 
  * If @a remove_ignored_children is @c TRUE, remove ignored unversioned children
  * of @a dir after successfull working copy cleanup.
  *
+ * When asked to remove unversioned or ignored items, and the working copy
+ * is already locked via a different client or WC context than @a ctx, return
+ * #SVN_ERR_WC_LOCKED. This prevents accidental working copy corruption in
+ * case users run the cleanup operation to remove unversioned items while
+ * another client is performing some other operation on the working copy.
+ *
  * If @a ctx->cancel_func is non-NULL, invoke it with @a
  * ctx->cancel_baton at various points during the operation.  If it
  * returns an error (typically #SVN_ERR_CANCELLED), return that error

Modified: subversion/trunk/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/cleanup.c?rev=1497310&r1=1497309&r2=1497310&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/cleanup.c (original)
+++ subversion/trunk/subversion/libsvn_client/cleanup.c Thu Jun 27 11:39:17 2013
@@ -117,6 +117,20 @@ svn_client_cleanup2(const char *path,
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
 
+  if (remove_unversioned_children || remove_ignored_children)
+    {
+      svn_boolean_t is_locked;
+
+      /* Check if someone else owns a lock for LOCAL_ABSPATH. */
+      SVN_ERR(svn_wc_locked2(NULL, &is_locked, ctx->wc_ctx,
+                             local_abspath, scratch_pool));
+      if (is_locked)
+        return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
+                                 _("Working copy at '%s' is already locked."),
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+    }
+
   err = svn_wc_cleanup3(ctx->wc_ctx, local_abspath, ctx->cancel_func,
                         ctx->cancel_baton, scratch_pool);
   svn_io_sleep_for_timestamps(path, scratch_pool);

Modified: subversion/trunk/subversion/svn/cleanup-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cleanup-cmd.c?rev=1497310&r1=1497309&r2=1497310&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cleanup-cmd.c (original)
+++ subversion/trunk/subversion/svn/cleanup-cmd.c Thu Jun 27 11:39:17 2013
@@ -80,6 +80,16 @@ svn_cl__cleanup(apr_getopt_t *os,
             {
               err =  svn_error_compose_create(err, err2);
             }
+          else if (opt_state->remove_unversioned || opt_state->remove_ignored)
+            {
+              err = svn_error_create(SVN_ERR_WC_LOCKED, err,
+                                     _("Working copy locked; if no other "
+                                       "Subversion client is currently "
+                                       "using the working copy, try running "
+                                       "'svn cleanup' without the "
+                                       "--remove-unversioned or "
+                                       "--remove-ignored options first."));
+            }
           else
             {
               const char *wcroot_abspath;

Modified: subversion/trunk/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1497310&r1=1497309&r2=1497310&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Thu Jun 27 11:39:17 2013
@@ -490,13 +490,27 @@ const svn_opt_subcommand_desc2_t svn_cl_
     {'r', 'q', 'N', opt_depth, opt_force, opt_ignore_externals} },
 
   { "cleanup", svn_cl__cleanup, {0}, N_
-    ("Recursively clean up the working copy, removing locks, resuming\n"
+    ("Recursively clean up the working copy, removing write locks, resuming\n"
      "unfinished operations, etc.\n"
      "usage: cleanup [WCPATH...]\n"
      "\n"
-     "  If the --remove-unversioned option is given, remove unversioned\n"
-     "  items within WCPATH. If --remove-ignored is given, remove ignored\n"
-     "  unversioned items within WCPATH.\n"),
+     "  By default, finish any unfinished business in the working copy at WCPATH,\n"
+     "  and remove write locks (shown as 'L' by the 'svn status' command) from\n"
+     "  the working copy. Usually, this is only necessary if a Subversion client\n"
+     "  has crashed while using the working copy, leaving it in an unusable state.\n"
+     "\n"
+     "  WARNING: There is no mechanism that will protect write locks still\n"
+     "           being used by other Subversion clients. Running this command\n"
+     "           while another client is using the working copy can corrupt\n"
+     "           the working copy beyond repair!\n"
+     "\n"
+     "  If the --remove-unversioned option or the --remove-ignored option\n"
+     "  is given, remove any unversioned or ignored items within WCPATH.\n"
+     "  To prevent accidental working copy corruption, unversioned or ignored\n"
+     "  items can only be removed if the working copy is not already locked\n"
+     "  for writing by another Subversion client.\n"
+     "  Note that the 'svn status' command shows unversioned items as '?',\n"
+     "  and ignored items as 'I' if the --no-ignore option is given to it.\n"),
     {opt_merge_cmd, opt_remove_unversioned, opt_remove_ignored} },
 
   { "commit", svn_cl__commit, {"ci"},

Modified: subversion/trunk/subversion/tests/cmdline/wc_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/wc_tests.py?rev=1497310&r1=1497309&r2=1497310&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/wc_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/wc_tests.py Thu Jun 27 11:39:17 2013
@@ -284,6 +284,22 @@ def cleanup_unversioned_items(sbox):
   svntest.actions.run_and_verify_svn(None, expected_output,
                                      [], 'status', '--no-ignore')
 
+def cleanup_unversioned_items_in_locked_wc(sbox):
+  """cleanup unversioned items in locked WC should fail"""
+
+  sbox.build(read_only = True)
+
+  contents = "This is an unversioned file\n."
+  svntest.main.file_write(sbox.ospath('unversioned_file'), contents)
+
+  svntest.actions.lock_admin_dir(sbox.ospath(""), True)
+  for option in ['--remove-unversioned', '--remove-ignored']:
+    svntest.actions.run_and_verify_svn(None, None,
+                                       "svn: E155004: Working copy locked;.*",
+                                       "cleanup", option,
+                                       sbox.ospath(""))
+
+
 ########################################################################
 # Run the tests
 
@@ -304,6 +320,7 @@ test_list = [ None,
               cleanup_below_wc_root,
               update_through_unversioned_symlink,
               cleanup_unversioned_items,
+              cleanup_unversioned_items_in_locked_wc,
              ]
 
 if __name__ == '__main__':