subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1497359 - in /subversion/trunk/subversion: include/svn_client.h include/svn_wc.h libsvn_client/cleanup.c libsvn_client/deprecated.c svn/cleanup-cmd.c svn/notify.c svn/svn.c tests/cmdline/wc_tests.py
Date Thu, 27 Jun 2013 13:59:59 GMT
Author: stsp
Date: Thu Jun 27 13:59:58 2013
New Revision: 1497359

URL: http://svn.apache.org/r1497359
Log:
Add support for cleaning up externals via 'svn cleanup --include-externals'.

* subversion/include/svn_client.h
  (svn_client_cleanup2): Add include_externals parameter.

* subversion/include/svn_wc.h
  (svn_wc_notify_t): New action svn_wc_notify_cleanup_external.

* subversion/libsvn_client/cleanup.c
  (remove_unversioned_items_baton): Rename to ...
  (cleanup_status_walk_baton): ... this, and replace notify/cancel support
   members with a client context member which includes them.
  (do_cleanup): New helper function, extracted from svn_client_cleanup2().
  (remove_unversioned_items): Rename to ...
  (cleanup_status_walk): ... this, and extend to optionally clean up externals
   found during the status walk. Adjust for baton changes, too.
  (svn_client_cleanup2): New parameter include_externals. Call the do_cleanup()
   helper function which replaces most of this function's body.

* subversion/libsvn_client/deprecated.c
  (svn_client_cleanup): Account for new parameter to svn_client_cleanup2().

* subversion/svn/cleanup-cmd.c
  (svn_cl__cleanup): Pass opt_state->include_externals to svn_client_cleanup2().

* subversion/svn/notify.c
  (notify): Handle svn_wc_notify_cleanup_external.

* subversion/svn/svn.c
  (svn_cl__cmd_table): Add --include-extenals option to 'svn cleanup'.

* subversion/tests/cmdline/wc_tests.py
  (cleanup_dir_external, test_list): New rather simple test.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_client/cleanup.c
    subversion/trunk/subversion/libsvn_client/deprecated.c
    subversion/trunk/subversion/svn/cleanup-cmd.c
    subversion/trunk/subversion/svn/notify.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=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Thu Jun 27 13:59:58 2013
@@ -4025,6 +4025,9 @@ svn_client_mergeinfo_log_eligible(const 
 /** Recursively cleanup a working copy directory @a dir, finishing any
  * incomplete operations, removing lockfiles, etc.
  *
+ * If @a include_externals is @c TRUE, recurse into externals and clean
+ * them up as well.
+ *
  * If @a remove_unversioned_children is @c TRUE, remove unversioned children
  * of @a dir after successfull working copy cleanup.
  * If @a remove_ignored_children is @c TRUE, remove ignored unversioned children
@@ -4047,12 +4050,14 @@ svn_client_mergeinfo_log_eligible(const 
  */
 svn_error_t *
 svn_client_cleanup2(const char *dir,
+                    svn_boolean_t include_externals,
                     svn_boolean_t remove_unversioned_children,
                     svn_boolean_t remove_ignored_children,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *scratch_pool);
 
-/* Like svn_client_cleanup2(), but no support for removing unversioned items.
+/* Like svn_client_cleanup2(), but no support for removing unversioned items
+ * and cleaning up externals.
  *
  * @deprecated Provided for limited backwards compatibility with the 1.8 API.
  */

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Thu Jun 27 13:59:58 2013
@@ -1255,7 +1255,11 @@ typedef enum svn_wc_notify_action_t
    * copy + delete. The notified path is the move source (the deleted path).
    * ### TODO: Provide path to move destination as well?
    * @since New in 1.8. */
-  svn_wc_notify_move_broken
+  svn_wc_notify_move_broken,
+
+  /** Running cleanup on an external module.
+   * @since New in 1.9. */
+  svn_wc_notify_cleanup_external,
 
 } svn_wc_notify_action_t;
 

Modified: subversion/trunk/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/cleanup.c?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/cleanup.c (original)
+++ subversion/trunk/subversion/libsvn_client/cleanup.c Thu Jun 27 13:59:58 2013
@@ -44,27 +44,132 @@
 
 /*** Code. ***/
 
-struct remove_unversioned_items_baton
+struct cleanup_status_walk_baton
 {
+  svn_boolean_t include_externals;
   svn_boolean_t remove_unversioned_items;
   svn_boolean_t remove_ignored_items;
-  svn_wc_notify_func2_t notify_func;
-  void *notify_baton;
-  svn_cancel_func_t cancel_func;
-  void *cancel_baton;
+  svn_client_ctx_t *ctx;
 };
 
+/* Forward declararion. */
+static svn_error_t *
+cleanup_status_walk(void *baton,
+                    const char *local_abspath,
+                    const svn_wc_status3_t *status,
+                    apr_pool_t *scratch_pool);
+
+static svn_error_t *
+do_cleanup(const char *local_abspath,
+           svn_boolean_t include_externals,
+           svn_boolean_t remove_unversioned_items,
+           svn_boolean_t remove_ignored_items,
+           svn_client_ctx_t *ctx,
+           apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+
+  if (remove_unversioned_items || remove_ignored_items)
+    {
+      svn_boolean_t is_locked_here;
+      svn_boolean_t is_locked;
+      svn_boolean_t sqlite_exclusive;
+      svn_config_t *cfg = ctx->config
+                          ? svn_hash_gets(ctx->config,
+                                          SVN_CONFIG_CATEGORY_CONFIG)
+                          : NULL;
+
+      /* Check if someone else owns a lock for LOCAL_ABSPATH. */
+      SVN_ERR(svn_wc_locked2(&is_locked_here, &is_locked, ctx->wc_ctx,
+                             local_abspath, scratch_pool));
+      if (is_locked && !is_locked_here)
+        return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
+                                 _("Working copy at '%s' is already locked."),
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+
+      SVN_ERR(svn_config_get_bool(cfg, &sqlite_exclusive,
+                                  SVN_CONFIG_SECTION_WORKING_COPY,
+                                  SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
+                                  FALSE));
+      if (sqlite_exclusive)
+        {
+          /* Close the db because svn_wc_cleanup3() will try to open it again,
+           * which doesn't work if exclusive sqlite locking mode is enabled. */
+          SVN_ERR(svn_wc__close_db(local_abspath, ctx->wc_ctx, scratch_pool));
+        }
+    }
+
+  err = svn_wc_cleanup3(ctx->wc_ctx, local_abspath, ctx->cancel_func,
+                        ctx->cancel_baton, scratch_pool);
+  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
+  if (err)
+    return svn_error_trace(err);
+
+  if (remove_unversioned_items || remove_ignored_items || include_externals)
+    {
+      struct cleanup_status_walk_baton b;
+
+      b.include_externals = include_externals;
+      b.remove_unversioned_items = remove_unversioned_items;
+      b.remove_ignored_items = remove_ignored_items;
+      b.include_externals = include_externals;
+      b.ctx = ctx;
+      SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
+                                 svn_depth_infinity,
+                                 TRUE,  /* get all */
+                                 remove_ignored_items,
+                                 TRUE,  /* ignore textmods */
+                                 NULL,  /* use default ignore patterns */
+                                 cleanup_status_walk, &b,
+                                 ctx->cancel_func,
+                                 ctx->cancel_baton,
+                                 scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 /* An implementation of svn_wc_status_func4_t. */
 static svn_error_t *
-remove_unversioned_items(void *baton,
-                         const char *local_abspath,
-                         const svn_wc_status3_t *status,
-                         apr_pool_t *scratch_pool)
+cleanup_status_walk(void *baton,
+                    const char *local_abspath,
+                    const svn_wc_status3_t *status,
+                    apr_pool_t *scratch_pool)
 {
-  struct remove_unversioned_items_baton *b = baton;
+  struct cleanup_status_walk_baton *b = baton;
   svn_node_kind_t kind_on_disk;
   svn_wc_notify_t *notify;
 
+  if (status->node_status == svn_wc_status_external && b->include_externals)
+    {
+      svn_error_t *err;
+
+      SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool));
+      if (kind_on_disk == svn_node_dir)
+        {
+          notify = svn_wc_create_notify(local_abspath,
+                                        svn_wc_notify_cleanup_external,
+                                        scratch_pool);
+          (*b->ctx->notify_func2)(b->ctx->notify_baton2, notify, scratch_pool);
+
+          err = do_cleanup(local_abspath, b->include_externals,
+                            b->remove_unversioned_items,
+                            b->remove_ignored_items,
+                            b->ctx, scratch_pool);
+          if (err && err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY)
+            {
+              svn_error_clear(err);
+              return SVN_NO_ERROR;
+            }
+          else
+            SVN_ERR(err);
+        }
+
+      return SVN_NO_ERROR;
+    }
+
   if (status->node_status == svn_wc_status_ignored)
     {
       if (!b->remove_ignored_items)
@@ -87,7 +192,7 @@ remove_unversioned_items(void *baton,
         break;
       case svn_node_dir:
         SVN_ERR(svn_io_remove_dir2(local_abspath, FALSE,
-                                   b->cancel_func, b->cancel_baton,
+                                   b->ctx->cancel_func, b->ctx->cancel_baton,
                                    scratch_pool));
         break;
       case svn_node_none:
@@ -98,85 +203,29 @@ remove_unversioned_items(void *baton,
   notify = svn_wc_create_notify(local_abspath, svn_wc_notify_delete,
                                 scratch_pool);
   notify->kind = kind_on_disk;
-  (*b->notify_func)(b->notify_baton, notify, scratch_pool);
+  (*b->ctx->notify_func2)(b->ctx->notify_baton2, notify, scratch_pool);
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
 svn_client_cleanup2(const char *path,
+                    svn_boolean_t include_externals,
                     svn_boolean_t remove_unversioned_children,
                     svn_boolean_t remove_ignored_children,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *scratch_pool)
 {
   const char *local_abspath;
-  svn_error_t *err;
 
   if (svn_path_is_url(path))
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                              _("'%s' is not a local path"), path);
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-
-  if (remove_unversioned_children || remove_ignored_children)
-    {
-      svn_boolean_t is_locked_here;
-      svn_boolean_t is_locked;
-      svn_boolean_t sqlite_exclusive;
-      svn_config_t *cfg = ctx->config
-                          ? svn_hash_gets(ctx->config,
-                                          SVN_CONFIG_CATEGORY_CONFIG)
-                          : NULL;
-
-      /* Check if someone else owns a lock for LOCAL_ABSPATH. */
-      SVN_ERR(svn_wc_locked2(&is_locked_here, &is_locked, ctx->wc_ctx,
-                             local_abspath, scratch_pool));
-      if (is_locked && !is_locked_here)
-        return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
-                                 _("Working copy at '%s' is already locked."),
-                                 svn_dirent_local_style(local_abspath,
-                                                        scratch_pool));
-
-      SVN_ERR(svn_config_get_bool(cfg, &sqlite_exclusive,
-                                  SVN_CONFIG_SECTION_WORKING_COPY,
-                                  SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
-                                  FALSE));
-      if (sqlite_exclusive)
-        {
-          /* Close the db because svn_wc_cleanup3() will try to open it again,
-           * which doesn't work if exclusive sqlite locking mode is enabled. */
-          SVN_ERR(svn_wc__close_db(local_abspath, ctx->wc_ctx, 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);
-  if (err)
-    return svn_error_trace(err);
- 
-  if (remove_unversioned_children || remove_ignored_children)
-    {
-      struct remove_unversioned_items_baton b;
-
-      b.remove_unversioned_items = remove_unversioned_children;
-      b.remove_ignored_items = remove_ignored_children;
-      b.notify_func = ctx->notify_func2;
-      b.notify_baton = ctx->notify_baton2;
-      b.cancel_func = ctx->cancel_func;
-      b.cancel_baton = ctx->cancel_baton;
-      SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
-                                 svn_depth_infinity,
-                                 TRUE,  /* get all */
-                                 remove_ignored_children,
-                                 TRUE,  /* ignore textmods */
-                                 NULL,  /* use default ignore patterns */
-                                 remove_unversioned_items, &b,
-                                 ctx->cancel_func,
-                                 ctx->cancel_baton,
-                                 scratch_pool));
-    }
+  SVN_ERR(do_cleanup(local_abspath, include_externals,
+                     remove_unversioned_children, remove_ignored_children,
+                     ctx, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Thu Jun 27 13:59:58 2013
@@ -2969,6 +2969,6 @@ svn_client_cleanup(const char *path,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_client_cleanup2(path, FALSE, FALSE, ctx,
+  return svn_error_trace(svn_client_cleanup2(path, FALSE, FALSE, FALSE, ctx,
                                              scratch_pool));
 }

Modified: subversion/trunk/subversion/svn/cleanup-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cleanup-cmd.c?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cleanup-cmd.c (original)
+++ subversion/trunk/subversion/svn/cleanup-cmd.c Thu Jun 27 13:59:58 2013
@@ -69,8 +69,10 @@ svn_cl__cleanup(apr_getopt_t *os,
 
       svn_pool_clear(subpool);
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
-      err = svn_client_cleanup2(target, opt_state->remove_unversioned,
-                                opt_state->remove_ignored, ctx, subpool);
+      err = svn_client_cleanup2(target, opt_state->include_externals,
+                                opt_state->remove_unversioned,
+                                opt_state->remove_ignored,
+                                ctx, subpool);
       if (err && err->apr_err == SVN_ERR_WC_LOCKED)
         {
           const char *target_abspath;

Modified: subversion/trunk/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/notify.c?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/notify.c (original)
+++ subversion/trunk/subversion/svn/notify.c Thu Jun 27 13:59:58 2013
@@ -1136,6 +1136,13 @@ notify(void *baton, const svn_wc_notify_
         goto print_error;
       break;
 
+    case svn_wc_notify_cleanup_external:
+      if ((err = svn_cmdline_printf
+           (pool, _("Performing cleanup on external item at '%s'.\n"),
+            path_local)))
+        goto print_error;
+      break;
+
     default:
       break;
     }

Modified: subversion/trunk/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Thu Jun 27 13:59:58 2013
@@ -511,7 +511,8 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "  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} },
+    {opt_merge_cmd, opt_remove_unversioned, opt_remove_ignored,
+     opt_include_externals} },
 
   { "commit", svn_cl__commit, {"ci"},
     N_("Send changes from your working copy to the repository.\n"

Modified: subversion/trunk/subversion/tests/cmdline/wc_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/wc_tests.py?rev=1497359&r1=1497358&r2=1497359&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/wc_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/wc_tests.py Thu Jun 27 13:59:58 2013
@@ -299,6 +299,20 @@ def cleanup_unversioned_items_in_locked_
                                        "cleanup", option,
                                        sbox.ospath(""))
 
+def cleanup_dir_external(sbox):
+  """cleanup --include-externals"""
+
+  sbox.build(read_only = True)
+
+  # configure a directory external
+  sbox.simple_propset("svn:externals", "^/A A_ext", ".")
+  sbox.simple_update()
+
+  svntest.actions.lock_admin_dir(sbox.ospath("A_ext"), True)
+  svntest.actions.run_and_verify_svn(None, ["Performing cleanup on external " +
+                                     "item at '%s'.\n" % sbox.ospath("A_ext")],
+                                     [], "cleanup", '--include-externals',
+                                     sbox.ospath(""))
 
 ########################################################################
 # Run the tests
@@ -321,6 +335,7 @@ test_list = [ None,
               update_through_unversioned_symlink,
               cleanup_unversioned_items,
               cleanup_unversioned_items_in_locked_wc,
+              cleanup_dir_external,
              ]
 
 if __name__ == '__main__':



Mime
View raw message