Author: stsp
Date: Sat Jul 22 15:04:57 2017
New Revision: 1802697
URL: http://svn.apache.org/viewvc?rev=1802697&view=rev
Log:
On the addremove branch, implement a new 'svn addremove' sub-command
with some basic support for it in libsvn_client.
* subversion/include/svn_client.h
(svn_client_addremove): Declare.
* subversion/libsvn_client/add.c
(add_file): Expose to other files in libsvn_client by renaming to ...
(svn_client__add_file): ... this.
(add_dir_recursive): For the same reason, rename this to ...
(svn_client__add_dir_recursive): ... this.
(add): Track renames.
* subversion/libsvn_client/addremove.c,
subversion/svn/addremove-cmd.c: New files with a basic implementation
which will be expanded upon later.
* subversion/libsvn_client/client.h
(svn_client__add_file, svn_client__add_dir_recursive): Declare.
* subversion/svn/cl.h
(svn_opt_subcommand_t): Add svn_cl__addremove.
* subversion/svn/svn.c
(svn_cl__cmd_table): Add the "addremove" subcommand.
* subversion/tests/cmdline/addremove_tests.py: New file, with one test so far.
Added:
subversion/branches/addremove/subversion/libsvn_client/addremove.c (with
props)
subversion/branches/addremove/subversion/svn/addremove-cmd.c (with props)
subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
(with props)
Modified:
subversion/branches/addremove/subversion/include/svn_client.h
subversion/branches/addremove/subversion/libsvn_client/add.c
subversion/branches/addremove/subversion/libsvn_client/client.h
subversion/branches/addremove/subversion/svn/cl.h
subversion/branches/addremove/subversion/svn/svn.c
Modified: subversion/branches/addremove/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/include/svn_client.h?rev=1802697&r1=1802696&r2=1802697&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/include/svn_client.h (original)
+++ subversion/branches/addremove/subversion/include/svn_client.h Sat Jul 22
15:04:57 2017
@@ -1674,6 +1674,20 @@ svn_client_add(const char *path,
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+/**
+ * Recurse into the versioned directory @a local_path, and put any unversioned
+ * nodes found into added status, and put any missing nodes found into deleted
+ * status.
+ *
+ * The level of recursion is specified by @a depth.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_addremove(const char *path,
+ svn_depth_t depth,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
/** @} */
/**
Modified: subversion/branches/addremove/subversion/libsvn_client/add.c
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_client/add.c?rev=1802697&r1=1802696&r2=1802697&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_client/add.c (original)
+++ subversion/branches/addremove/subversion/libsvn_client/add.c Sat Jul 22
15:04:57 2017
@@ -265,14 +265,13 @@ svn_client__get_paths_auto_props(apr_has
return SVN_NO_ERROR;
}
-/* Only call this if the on-disk node kind is a file. */
-static svn_error_t *
-add_file(const char *local_abspath,
- svn_magic__cookie_t *magic_cookie,
- apr_hash_t *autoprops,
- svn_boolean_t no_autoprops,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
+svn_error_t *
+svn_client__add_file(const char *local_abspath,
+ svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *autoprops,
+ svn_boolean_t no_autoprops,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
{
apr_hash_t *properties;
const char *mimetype;
@@ -324,48 +323,18 @@ add_file(const char *local_abspath,
return SVN_NO_ERROR;
}
-/* Schedule directory DIR_ABSPATH, and some of the tree under it, for
- * addition. DEPTH is the depth at this point in the descent (it may
- * be changed for recursive calls).
- *
- * If DIR_ABSPATH (or any item below DIR_ABSPATH) is already scheduled for
- * addition, add will fail and return an error unless FORCE is TRUE.
- *
- * Use MAGIC_COOKIE (which may be NULL) to detect the mime-type of files
- * if necessary.
- *
- * If not NULL, CONFIG_AUTOPROPS is a hash representing the config file and
- * svn:auto-props autoprops which apply to DIR_ABSPATH. It maps
- * const char * file patterns to another hash which maps const char *
- * property names to const char *property values. If CONFIG_AUTOPROPS is
- * NULL and the config file and svn:auto-props autoprops are required by this
- * function, then such will be obtained.
- *
- * If IGNORES is not NULL, then it is an array of const char * ignore patterns
- * that apply to any children of DIR_ABSPATH. If REFRESH_IGNORES is TRUE, then
- * the passed in value of IGNORES (if any) is itself ignored and this function
- * will gather all ignore patterns applicable to DIR_ABSPATH itself (allocated
in
- * RESULT_POOL). Any recursive calls to this function get the refreshed ignore
- * patterns. If IGNORES is NULL and REFRESH_IGNORES is FALSE, then all
children of DIR_ABSPATH
- * are unconditionally added.
- *
- * If CTX->CANCEL_FUNC is non-null, call it with CTX->CANCEL_BATON to allow
- * the user to cancel the operation.
- *
- * Use SCRATCH_POOL for temporary allocations.
- */
-static svn_error_t *
-add_dir_recursive(const char *dir_abspath,
- svn_depth_t depth,
- svn_boolean_t force,
- svn_boolean_t no_autoprops,
- svn_magic__cookie_t *magic_cookie,
- apr_hash_t *config_autoprops,
- svn_boolean_t refresh_ignores,
- apr_array_header_t *ignores,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_error_t *
+svn_client__add_dir_recursive(const char *dir_abspath,
+ svn_depth_t depth,
+ svn_boolean_t force,
+ svn_boolean_t no_autoprops,
+ svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *config_autoprops,
+ svn_boolean_t refresh_ignores,
+ apr_array_header_t *ignores,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_error_t *err;
apr_pool_t *iterpool;
@@ -412,8 +381,8 @@ add_dir_recursive(const char *dir_abspat
Since this set of autoprops applies to all unversioned children of
DIR_ABSPATH, we will pass these along to any recursive calls to
- add_dir_recursive() and calls to add_file() below. Thus sparing
- these callees from looking up the same information. */
+ svn_client__add_dir_recursive() and calls to svn_client__add_file() below.
+ Thus sparing these callees from looking up the same information. */
if (!entry_exists && config_autoprops == NULL)
{
SVN_ERR(svn_client__get_all_auto_props(&config_autoprops, dir_abspath,
@@ -463,17 +432,17 @@ add_dir_recursive(const char *dir_abspat
if (refresh_ignores && !entry_exists)
refresh_ignores = FALSE;
- SVN_ERR(add_dir_recursive(abspath, depth_below_here,
- force, no_autoprops,
- magic_cookie, config_autoprops,
- refresh_ignores, ignores, ctx,
- result_pool, iterpool));
+ SVN_ERR(svn_client__add_dir_recursive(abspath, depth_below_here,
+ force, no_autoprops,
+ magic_cookie, config_autoprops,
+ refresh_ignores, ignores, ctx,
+ result_pool, iterpool));
}
else if ((dirent->kind == svn_node_file || dirent->special)
&& depth >= svn_depth_files)
{
- err = add_file(abspath, magic_cookie, config_autoprops,
- no_autoprops, ctx, iterpool);
+ err = svn_client__add_file(abspath, magic_cookie, config_autoprops,
+ no_autoprops, ctx, iterpool);
if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
svn_error_clear(err);
else
@@ -835,17 +804,17 @@ add(const char *local_abspath,
SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
if (kind == svn_node_dir)
{
- /* We use add_dir_recursive for all directory targets
+ /* We use svn_client__add_dir_recursive for all directory targets
and pass depth along no matter what it is, so that the
target's depth will be set correctly. */
- err = add_dir_recursive(local_abspath, depth, force,
- no_autoprops, magic_cookie, NULL,
- !no_ignore, ignores, ctx,
- scratch_pool, scratch_pool);
+ err = svn_client__add_dir_recursive(local_abspath, depth, force,
+ no_autoprops, magic_cookie, NULL,
+ !no_ignore, ignores, ctx,
+ scratch_pool, scratch_pool);
}
else if (kind == svn_node_file)
- err = add_file(local_abspath, magic_cookie, NULL,
- no_autoprops, ctx, scratch_pool);
+ err = svn_client__add_file(local_abspath, magic_cookie, NULL,
+ no_autoprops, ctx, scratch_pool);
else if (kind == svn_node_none)
{
svn_boolean_t tree_conflicted;
Added: subversion/branches/addremove/subversion/libsvn_client/addremove.c
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_client/addremove.c?rev=1802697&view=auto
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_client/addremove.c (added)
+++ subversion/branches/addremove/subversion/libsvn_client/addremove.c Sat Jul
22 15:04:57 2017
@@ -0,0 +1,194 @@
+/*
+ * addremove.c: integrate unversioned structural changes into working copy
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include "svn_hash.h"
+#include "svn_wc.h"
+#include "svn_client.h"
+#include "svn_pools.h"
+#include "svn_error.h"
+#include "svn_dirent_uri.h"
+#include "svn_io.h"
+#include "client.h"
+
+#include "private/svn_client_private.h"
+#include "private/svn_wc_private.h"
+
+#include "svn_private_config.h"
+
+
+
+/*** Code. ***/
+
+struct addremove_status_baton {
+ /* Status info for missing paths. */
+ apr_hash_t *missing;
+
+ /* Status info for unversioned paths. */
+ apr_hash_t *unversioned;
+};
+
+/* Implements svn_wc_status_func4_t. */
+static svn_error_t *
+addremove_status_func(void *baton, const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
+ struct addremove_status_baton *b = baton;
+
+ switch (status->node_status)
+ {
+ case svn_wc_status_unversioned:
+ {
+ apr_hash_t *hash = b->unversioned;
+ apr_pool_t *result_pool = apr_hash_pool_get(hash);
+
+ svn_hash_sets(hash, apr_pstrdup(result_pool, local_abspath),
+ svn_wc_dup_status3(status, result_pool));
+ break;
+ }
+
+ case svn_wc_status_missing:
+ {
+
+ apr_hash_t *hash = b->missing;
+ apr_pool_t *result_pool = apr_hash_pool_get(hash);
+
+ svn_hash_sets(hash, apr_pstrdup(result_pool, local_abspath),
+ svn_wc_dup_status3(status, result_pool));
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+addremove(const char *local_abspath, svn_depth_t depth,
+ svn_client_ctx_t *ctx, apr_pool_t *scratch_pool)
+{
+ struct addremove_status_baton b;
+ struct svn_wc_status3_t *status;
+ svn_node_kind_t kind_on_disk;
+ apr_hash_index_t *hi;
+ apr_pool_t *iterpool;
+
+ /* Our target must be a versioned directory. */
+ SVN_ERR(svn_wc_status3(&status, ctx->wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool));
+ if (status->kind != svn_node_dir || kind_on_disk != svn_node_dir ||
+ !status->versioned)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("'%s' is not a versioned directory"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ b.missing = apr_hash_make(scratch_pool);
+ b.unversioned = apr_hash_make(scratch_pool);
+
+ SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath, depth,
+ TRUE, FALSE, FALSE, NULL,
+ addremove_status_func, &b,
+ ctx->cancel_func, ctx->cancel_baton,
+ scratch_pool));
+
+ iterpool = svn_pool_create(scratch_pool);
+ for (hi = apr_hash_first(scratch_pool, b.unversioned); hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *unversioned_abspath = apr_hash_this_key(hi);
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_io_check_path(unversioned_abspath, &kind_on_disk,
+ scratch_pool));
+
+ if (kind_on_disk == svn_node_file)
+ {
+ SVN_ERR(svn_client__add_file(unversioned_abspath,
+ NULL, /* TODO: magic cookie */
+ NULL, /* TODO: autoprops */
+ TRUE, /* TODO: !no_autoprops */
+ ctx, iterpool));
+ }
+ else if (kind_on_disk == svn_node_dir && depth >= svn_depth_immediates)
+ {
+ svn_depth_t depth_below_here = depth;
+
+ if (depth == svn_depth_immediates)
+ depth_below_here = svn_depth_empty;
+
+ SVN_ERR(svn_client__add_dir_recursive(
+ unversioned_abspath, depth_below_here,
+ FALSE, /* force */
+ TRUE, /* TODO: !no_autoprops */
+ NULL, /* TODO: magic cookie */
+ NULL, /* TODO: autoprops */
+ FALSE, /* TODO: refresh_ignores */
+ NULL, /* TODO: ignores */
+ ctx, iterpool, iterpool));
+ }
+ }
+ svn_pool_destroy(iterpool);
+
+ for (hi = apr_hash_first(scratch_pool, b.missing); hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *missing_abspath = apr_hash_this_key(hi);
+
+ SVN_ERR(svn_wc_delete4(ctx->wc_ctx, missing_abspath,
+ FALSE, /* keep_local */
+ FALSE, /* delete_unversioned_target */
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2,
+ scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_addremove(const char *local_path,
+ svn_depth_t depth,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *local_abspath;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, local_path, scratch_pool));
+
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ addremove(local_abspath, depth, ctx, scratch_pool),
+ ctx->wc_ctx, local_abspath, TRUE, scratch_pool);
+
+ return SVN_NO_ERROR;
+}
Propchange: subversion/branches/addremove/subversion/libsvn_client/addremove.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/addremove/subversion/libsvn_client/client.h
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_client/client.h?rev=1802697&r1=1802696&r2=1802697&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_client/client.h (original)
+++ subversion/branches/addremove/subversion/libsvn_client/client.h Sat Jul 22
15:04:57 2017
@@ -1267,6 +1267,59 @@ svn_client__merge_locked(svn_client__con
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Internal helper for svn_client_add() and svn_client_addremove().
+ * Only call this if the on-disk node kind is a file. */
+svn_error_t *
+svn_client__add_file(const char *local_abspath,
+ svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *autoprops,
+ svn_boolean_t no_autoprops,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/* Schedule directory DIR_ABSPATH, and some of the tree under it, for
+ * addition. DEPTH is the depth at this point in the descent (it may
+ * be changed for recursive calls).
+ *
+ * If DIR_ABSPATH (or any item below DIR_ABSPATH) is already scheduled for
+ * addition, add will fail and return an error unless FORCE is TRUE.
+ *
+ * Use MAGIC_COOKIE (which may be NULL) to detect the mime-type of files
+ * if necessary.
+ *
+ * If not NULL, CONFIG_AUTOPROPS is a hash representing the config file and
+ * svn:auto-props autoprops which apply to DIR_ABSPATH. It maps
+ * const char * file patterns to another hash which maps const char *
+ * property names to const char *property values. If CONFIG_AUTOPROPS is
+ * NULL and the config file and svn:auto-props autoprops are required by this
+ * function, then such will be obtained.
+ *
+ * If IGNORES is not NULL, then it is an array of const char * ignore patterns
+ * that apply to any children of DIR_ABSPATH. If REFRESH_IGNORES is TRUE, then
+ * the passed in value of IGNORES (if any) is itself ignored and this function
+ * will gather all ignore patterns applicable to DIR_ABSPATH itself (allocated
in
+ * RESULT_POOL). Any recursive calls to this function get the refreshed ignore
+ * patterns. If IGNORES is NULL and REFRESH_IGNORES is FALSE, then all
children of DIR_ABSPATH
+ * are unconditionally added.
+ *
+ * If CTX->CANCEL_FUNC is non-null, call it with CTX->CANCEL_BATON to allow
+ * the user to cancel the operation.
+ *
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+svn_client__add_dir_recursive(const char *dir_abspath,
+ svn_depth_t depth,
+ svn_boolean_t force,
+ svn_boolean_t no_autoprops,
+ svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *config_autoprops,
+ svn_boolean_t refresh_ignores,
+ apr_array_header_t *ignores,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Added: subversion/branches/addremove/subversion/svn/addremove-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/addremove-cmd.c?rev=1802697&view=auto
==============================================================================
--- subversion/branches/addremove/subversion/svn/addremove-cmd.c (added)
+++ subversion/branches/addremove/subversion/svn/addremove-cmd.c Sat Jul 22
15:04:57 2017
@@ -0,0 +1,106 @@
+/*
+ * addremove-cmd.c -- Subversion addremove command
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+#define APR_WANT_STDIO
+#include <apr_want.h>
+
+#include "svn_client.h"
+#include "svn_error.h"
+#include "svn_pools.h"
+#include "cl.h"
+
+#include "svn_private_config.h"
+
+
+/*** Code. ***/
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__addremove(apr_getopt_t *os,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+ svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+ apr_array_header_t *targets;
+ int i;
+ apr_pool_t *iterpool;
+ apr_array_header_t *errors = apr_array_make(pool, 0, sizeof(apr_status_t));
+
+ SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+ opt_state->targets,
+ ctx, FALSE, pool));
+
+ if (! targets->nelts)
+ return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+
+ if (opt_state->depth == svn_depth_unknown)
+ opt_state->depth = svn_depth_infinity;
+
+ SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
+
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ svn_pool_clear(iterpool);
+ SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
+ SVN_ERR(svn_cl__try
+ (svn_client_addremove(target, opt_state->depth, ctx, iterpool),
+ errors, opt_state->quiet,
+ SVN_ERR_ENTRY_EXISTS,
+ SVN_ERR_WC_PATH_NOT_FOUND,
+ 0));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ if (errors->nelts > 0)
+ {
+ svn_error_t *err;
+
+ err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
+ for (i = 0; i < errors->nelts; i++)
+ {
+ apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
+ if (status == SVN_ERR_WC_PATH_NOT_FOUND)
+ err = svn_error_quick_wrap(err,
+ _("Could not add all targets because "
+ "some targets don't exist"));
+ else if (status == SVN_ERR_ENTRY_EXISTS)
+ err = svn_error_quick_wrap(err,
+ _("Could not add all targets because "
+ "some targets are already
versioned"));
+ }
+
+ return svn_error_trace(err);
+ }
+
+ return SVN_NO_ERROR;
+}
Propchange: subversion/branches/addremove/subversion/svn/addremove-cmd.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/addremove/subversion/svn/cl.h
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/cl.h?rev=1802697&r1=1802696&r2=1802697&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/svn/cl.h (original)
+++ subversion/branches/addremove/subversion/svn/cl.h Sat Jul 22 15:04:57 2017
@@ -266,6 +266,7 @@ typedef struct svn_cl__cmd_baton_t
/* Declare all the command procedures */
svn_opt_subcommand_t
svn_cl__add,
+ svn_cl__addremove,
svn_cl__auth,
svn_cl__blame,
svn_cl__cat,
Modified: subversion/branches/addremove/subversion/svn/svn.c
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svn/svn.c?rev=1802697&r1=1802696&r2=1802697&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/svn/svn.c (original)
+++ subversion/branches/addremove/subversion/svn/svn.c Sat Jul 22 15:04:57 2017
@@ -513,6 +513,23 @@ const svn_opt_subcommand_desc2_t svn_cl_
opt_no_autoprops, opt_parents },
{{opt_parents, N_("add intermediate parents")}} },
+ { "addremove", svn_cl__addremove, {0}, N_
+ ("Put unversioned and missing items under version control.\n"
+ "usage: addremove PATH...\n"
+ "\n"
+ " Recursively walk the specified paths in the working copy, putting\n"
+ " unversioned files and directories under version control, and
removing\n"
+ " missing files and directories from version control.\n"
+ "\n"
+ " The specified PATHs must be versioned directories.\n"
+ "\n"
+ " Additions and deletions will be scheduled for the next commit and\n"
+ " will not take effect in the repository unless they are committed.\n"
+ "\n"
+ " The --depth option controls recursion (default: infinity).\n"
+ " Use 'svn revert' to undo any undesirable additions and deletions.\n"),
+ {opt_targets, opt_depth }, },
+
{ "auth", svn_cl__auth, {0}, N_
("Manage cached authentication credentials.\n"
"usage: 1. svn auth [PATTERN ...]\n"
Added: subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
URL:
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py?rev=1802697&view=auto
==============================================================================
--- subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
(added)
+++ subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
Sat Jul 22 15:04:57 2017
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# addremove_tests.py: testing svn addremove
+#
+# Subversion is a tool for revision control.
+# See http://subversion.apache.org for more information.
+#
+# ====================================================================
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+######################################################################
+
+# General modules
+import shutil, stat, re, os, logging
+
+logger = logging.getLogger()
+
+# Our testing module
+import svntest
+from svntest import wc
+
+# (abbreviation)
+Skip = svntest.testcase.Skip_deco
+SkipUnless = svntest.testcase.SkipUnless_deco
+XFail = svntest.testcase.XFail_deco
+Issues = svntest.testcase.Issues_deco
+Issue = svntest.testcase.Issue_deco
+Wimp = svntest.testcase.Wimp_deco
+Item = wc.StateItem
+
+######################################################################
+# Tests
+#
+# Each test must return on success or raise on failure.
+
+#----------------------------------------------------------------------
+
+def basic_addremove(sbox):
+ "basic addremove functionality"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Delete a file
+ lambda_path = sbox.ospath('A/B/lambda')
+ os.remove(lambda_path)
+
+ # Delete a directory
+ C_path = sbox.ospath('A/C')
+ os.rmdir(C_path)
+
+ # Add an unversioned directory
+ newdir_path = sbox.ospath('A/newdir')
+ os.mkdir(newdir_path)
+
+ # Add an unversioned file inside the new directory
+ newfile_path = sbox.ospath('A/newdir/newfile')
+ svntest.main.file_append(newfile_path, 'This is a new file\n')
+
+ svntest.actions.run_and_verify_svn(None, [], 'addremove', wc_dir)
+
+ expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_output.tweak('A/B/lambda', status='D ')
+ expected_output.tweak('A/C', status='D ')
+ expected_output.add({
+ 'A/newdir' : Item(status='A ', wc_rev=0),
+ 'A/newdir/newfile' : Item(status='A ', wc_rev=0),
+ })
+
+ svntest.actions.run_and_verify_status(wc_dir, expected_output)
+
+########################################################################
+# Run the tests
+
+# list all tests here, starting with None:
+test_list = [ None,
+ basic_addremove,
+]
+
+if __name__ == '__main__':
+ svntest.main.run_tests(test_list)
Propchange:
subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
------------------------------------------------------------------------------
svn:executable = *