You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2017/07/11 11:55:45 UTC
svn commit: r1801595 - in /subversion/branches/shelve-checkpoint:
subversion/include/ subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_wc/ subversion/svn/ tools/client-side/
Author: julianfoad
Date: Tue Jul 11 11:55:45 2017
New Revision: 1801595
URL: http://svn.apache.org/viewvc?rev=1801595&view=rev
Log:
Implement svn shelving, in prototype form.
Commands are:
svn shelve NAME PATH...
svn shelve --delete NAME
svn shelves OR svn shelve --list
svn unshelve [--keep] NAME
* subversion/include/private/svn_wc_private.h,
subversion/libsvn_wc/wcroot_anchor.c
(svn_wc__get_shelves_dir): New function.
* subversion/include/svn_client.h
(svn_client_shelve,
svn_client_unshelve,
svn_client_shelves_delete,
svn_client_shelves_list): New functions.
* subversion/libsvn_client/shelve.c
New file.
* subversion/svn/cl.h
(svn_cl__opt_state_t): Add the '--list' option.
(svn_cl__shelve,
svn_cl__unshelve,
svn_cl__shelves): New.
* subversion/svn/shelve-cmd.c
New file.
* subversion/svn/svn.c
Add the new commands and options.
* tools/client-side/bash_completion
(_svn): Add the 'shelve' commands and options.
Added:
subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelve.c (with props)
subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c (with props)
Modified:
subversion/branches/shelve-checkpoint/subversion/include/private/svn_wc_private.h
subversion/branches/shelve-checkpoint/subversion/include/svn_client.h
subversion/branches/shelve-checkpoint/subversion/libsvn_wc/wcroot_anchor.c
subversion/branches/shelve-checkpoint/subversion/svn/cl.h
subversion/branches/shelve-checkpoint/subversion/svn/svn.c
subversion/branches/shelve-checkpoint/tools/client-side/bash_completion
Modified: subversion/branches/shelve-checkpoint/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/private/svn_wc_private.h?rev=1801595&r1=1801594&r2=1801595&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/shelve-checkpoint/subversion/include/private/svn_wc_private.h Tue Jul 11 11:55:45 2017
@@ -348,6 +348,14 @@ svn_wc__get_wcroot(const char **wcroot_a
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* */
+svn_error_t *
+svn_wc__get_shelves_dir(char **dir,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/**
* The following are temporary APIs to aid in the transition from wc-1 to
* wc-ng. Use them for new development now, but they may be disappearing
Modified: subversion/branches/shelve-checkpoint/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/include/svn_client.h?rev=1801595&r1=1801594&r2=1801595&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/include/svn_client.h (original)
+++ subversion/branches/shelve-checkpoint/subversion/include/svn_client.h Tue Jul 11 11:55:45 2017
@@ -6716,6 +6716,61 @@ svn_client_cat(svn_stream_t *out,
+/** Shelving commands
+ *
+ * @defgroup svn_client_shelve_funcs Client Shelving Functions
+ * @{
+ */
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_shelve(const char *shelf_name,
+ const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_unshelve(const char *shelf_name,
+ const char *local_abspath,
+ svn_boolean_t keep,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_shelves_delete(const char *shelf_name,
+ const char *local_abspath,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ *
+ * @since New in 1.11.
+ */
+svn_error_t *
+svn_client_shelves_list(apr_hash_t **dirents,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** @} */
+
/** Changelist commands
*
* @defgroup svn_client_changelist_funcs Client Changelist Functions
Added: subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelve.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelve.c?rev=1801595&view=auto
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelve.c (added)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelve.c Tue Jul 11 11:55:45 2017
@@ -0,0 +1,317 @@
+/*
+ * shelve.c: implementation of the 'shelve' commands
+ *
+ * ====================================================================
+ * 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_client.h"
+#include "svn_wc.h"
+#include "svn_pools.h"
+#include "svn_dirent_uri.h"
+#include "svn_path.h"
+#include "svn_hash.h"
+#include "svn_utf.h"
+
+#include "client.h"
+#include "private/svn_wc_private.h"
+#include "svn_private_config.h"
+
+
+/* */
+static svn_error_t *
+validate_shelf_name(const char *shelf_name,
+ apr_pool_t *scratch_pool)
+{
+ if (shelf_name[0] == '\0' || strchr(shelf_name, '/'))
+ return svn_error_createf(SVN_ERR_BAD_CHANGELIST_NAME, NULL,
+ _("Shelve: Bad name '%s'"), shelf_name);
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+get_patch_abspath(char **patch_abspath,
+ const char *local_path,
+ const char *shelf_name,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ char *dir;
+ const char *local_abspath;
+ const char *filename;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, local_path, scratch_pool));
+ SVN_ERR(svn_wc__get_shelves_dir(&dir, ctx->wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ filename = apr_pstrcat(scratch_pool, shelf_name, ".patch", SVN_VA_NULL);
+ *patch_abspath = svn_dirent_join(dir, filename, result_pool);
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+write_patch(const char *patch_abspath,
+ const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ svn_stream_t *outstream;
+ svn_stream_t *errstream;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int i;
+ svn_opt_revision_t peg_revision = {svn_opt_revision_unspecified, {0}};
+ svn_opt_revision_t start_revision = {svn_opt_revision_base, {0}};
+ svn_opt_revision_t end_revision = {svn_opt_revision_working, {0}};
+
+ /* Get streams for the output and any error output of the diff. */
+ SVN_ERR(svn_stream_open_writable(&outstream, patch_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_stream_for_stderr(&errstream, scratch_pool));
+
+ for (i = 0; i < paths->nelts; i++)
+ {
+ const char *path = APR_ARRAY_IDX(paths, i, const char *);
+
+ 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_client_diff_peg6(
+ NULL /*options*/,
+ path,
+ &peg_revision,
+ &start_revision,
+ &end_revision,
+ NULL,
+ depth,
+ TRUE /*notice_ancestry*/,
+ FALSE /*no_diff_added*/,
+ FALSE /*no_diff_deleted*/,
+ TRUE /*show_copies_as_adds*/,
+ FALSE /*ignore_content_type: FALSE -> omit binary files*/,
+ FALSE /*ignore_properties*/,
+ FALSE /*properties_only*/,
+ FALSE /*use_git_diff_format*/,
+ SVN_APR_LOCALE_CHARSET,
+ outstream,
+ errstream,
+ changelists,
+ ctx, iterpool));
+ }
+ SVN_ERR(svn_stream_close(outstream));
+ SVN_ERR(svn_stream_close(errstream));
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+apply_patch(const char *patch_abspath,
+ const char *wc_dir_abspath,
+ svn_boolean_t reverse,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(svn_client_patch(patch_abspath, wc_dir_abspath,
+ dry_run, 0 /*strip*/,
+ reverse,
+ FALSE /*ignore_whitespace*/,
+ TRUE /*remove_tempfiles*/, NULL, NULL,
+ ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+delete_patch(const char *patch_abspath,
+ apr_pool_t *pool)
+{
+ SVN_ERR(svn_io_remove_file2(patch_abspath, FALSE /*ignore_enoent*/, pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_shelve(const char *shelf_name,
+ const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ const char *local_abspath;
+ const char *wc_root_abspath;
+ char *patch_abspath;
+ svn_error_t *err;
+
+ SVN_ERR(validate_shelf_name(shelf_name, pool));
+
+ /* ### TODO: check all paths are in same WC; for now use first path */
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath,
+ APR_ARRAY_IDX(paths, 0, char *), pool));
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath,
+ local_abspath, ctx, pool, pool));
+ SVN_ERR(get_patch_abspath(&patch_abspath,
+ wc_root_abspath, shelf_name, ctx, pool, pool));
+
+ err = write_patch(patch_abspath, paths, depth, changelists, ctx, pool);
+ if (err && APR_STATUS_IS_EEXIST(err->apr_err))
+ {
+ return svn_error_quick_wrapf(err,
+ "Shelved change '%s' already exists",
+ shelf_name);
+ }
+ else
+ SVN_ERR(err);
+
+ /* Reverse-apply the patch. This should be a safer way to remove those
+ changes from the WC than running a 'revert' operation. */
+ SVN_ERR(apply_patch(patch_abspath, wc_root_abspath,
+ TRUE /*reverse*/,
+ dry_run,
+ ctx, pool));
+
+ if (dry_run)
+ {
+ SVN_ERR(delete_patch(patch_abspath, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_unshelve(const char *shelf_name,
+ const char *local_abspath,
+ svn_boolean_t keep,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ const char *wc_root_abspath;
+ char *patch_abspath;
+ svn_error_t *err;
+
+ SVN_ERR(validate_shelf_name(shelf_name, pool));
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath,
+ local_abspath, ctx, pool, pool));
+ SVN_ERR(get_patch_abspath(&patch_abspath,
+ local_abspath, shelf_name, ctx, pool, pool));
+
+ /* Apply the patch. */
+ err = apply_patch(patch_abspath, wc_root_abspath,
+ FALSE /*reverse*/,
+ dry_run /*dry_run*/,
+ ctx, pool);
+ if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET)
+ {
+ return svn_error_quick_wrapf(err,
+ "Shelved change '%s' not found",
+ shelf_name);
+ }
+ else
+ SVN_ERR(err);
+
+ /* Remove the patch. */
+ if (! keep && ! dry_run)
+ {
+ SVN_ERR(delete_patch(patch_abspath, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_shelves_delete(const char *shelf_name,
+ const char *local_abspath,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ const char *wc_root_abspath;
+ char *patch_abspath;
+
+ SVN_ERR(validate_shelf_name(shelf_name, pool));
+
+ SVN_ERR(svn_client_get_wc_root(&wc_root_abspath,
+ local_abspath, ctx, pool, pool));
+ SVN_ERR(get_patch_abspath(&patch_abspath,
+ local_abspath, shelf_name, ctx, pool, pool));
+
+ /* Remove the patch. */
+ if (! dry_run)
+ {
+ svn_error_t *err;
+
+ err = delete_patch(patch_abspath, pool);
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ return svn_error_quick_wrapf(err,
+ "Shelved change '%s' not found",
+ shelf_name);
+ }
+ else
+ SVN_ERR(err);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_shelves_list(apr_hash_t **dirents,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ char *shelves_dir;
+ apr_hash_index_t *hi;
+
+ SVN_ERR(svn_wc__get_shelves_dir(&shelves_dir, ctx->wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_io_get_dirents3(dirents, shelves_dir, TRUE /*only_check_type*/,
+ result_pool, scratch_pool));
+
+ /* Remove non-shelves */
+ for (hi = apr_hash_first(scratch_pool, *dirents); hi; hi = apr_hash_next(hi))
+ {
+ const char *name = apr_hash_this_key(hi);
+
+ if (! strstr(name, ".patch"))
+ {
+ svn_hash_sets(*dirents, name, NULL);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
Propchange: subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelve.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/shelve-checkpoint/subversion/libsvn_wc/wcroot_anchor.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/libsvn_wc/wcroot_anchor.c?rev=1801595&r1=1801594&r2=1801595&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/libsvn_wc/wcroot_anchor.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/libsvn_wc/wcroot_anchor.c Tue Jul 11 11:55:45 2017
@@ -183,6 +183,26 @@ svn_wc__get_wcroot(const char **wcroot_a
svn_error_t *
+svn_wc__get_shelves_dir(char **dir,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *wc_adm_dir;
+
+ SVN_ERR(svn_wc__get_wcroot(&wc_adm_dir, wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ *dir = svn_dirent_join(wc_adm_dir, ".svn/shelves", result_pool);
+
+ /* Ensure the directory exists. (Other versions of svn don't create it.) */
+ SVN_ERR(svn_io_make_dir_recursively(*dir, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
svn_wc_get_actual_target2(const char **anchor,
const char **target,
svn_wc_context_t *wc_ctx,
Modified: subversion/branches/shelve-checkpoint/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svn/cl.h?rev=1801595&r1=1801594&r2=1801595&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/svn/cl.h (original)
+++ subversion/branches/shelve-checkpoint/subversion/svn/cl.h Tue Jul 11 11:55:45 2017
@@ -250,6 +250,7 @@ typedef struct svn_cl__opt_state_t
svn_boolean_t pin_externals; /* pin externals to last-changed revisions */
const char *show_item; /* print only the given item */
svn_boolean_t adds_as_modification; /* update 'add vs add' no tree conflict */
+ svn_boolean_t list;
} svn_cl__opt_state_t;
/* Conflict stats for operations such as update and merge. */
@@ -297,6 +298,9 @@ svn_opt_subcommand_t
svn_cl__revert,
svn_cl__resolve,
svn_cl__resolved,
+ svn_cl__shelve,
+ svn_cl__unshelve,
+ svn_cl__shelves,
svn_cl__status,
svn_cl__switch,
svn_cl__unlock,
Added: subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c?rev=1801595&view=auto
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c (added)
+++ subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c Tue Jul 11 11:55:45 2017
@@ -0,0 +1,198 @@
+/*
+ * shelve-cmd.c -- Shelve commands.
+ *
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ */
+
+#include "svn_client.h"
+#include "svn_error_codes.h"
+#include "svn_error.h"
+#include "svn_path.h"
+#include "svn_utf.h"
+
+#include "cl.h"
+
+#include "svn_private_config.h"
+
+
+/* First argument should be the name of a shelve. */
+static svn_error_t *
+get_shelf_name(const char **shelf_name,
+ apr_getopt_t *os,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *args;
+
+ SVN_ERR(svn_opt_parse_num_args(&args, os, 1, scratch_pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(shelf_name,
+ APR_ARRAY_IDX(args, 0, const char *),
+ result_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Display a list of shelves */
+static svn_error_t *
+shelves_list(const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ apr_hash_t *dirents;
+ apr_hash_index_t *hi;
+
+ SVN_ERR(svn_client_shelves_list(&dirents, local_abspath, ctx, pool, pool));
+
+ for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))
+ {
+ const char *name = apr_hash_this_key(hi);
+
+ if (strstr(name, ".patch"))
+ {
+ printf("%s\n", name);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__shelve(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;
+ const char *local_abspath;
+ const char *shelf_name;
+ apr_array_header_t *targets;
+
+ if (opt_state->quiet)
+ ctx->notify_func2 = NULL; /* Easy out: avoid unneeded work */
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
+
+ if (opt_state->list)
+ {
+ if (os->ind < os->argc)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+
+ SVN_ERR(shelves_list(local_abspath, ctx, pool));
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(get_shelf_name(&shelf_name, os, pool, pool));
+
+ if (opt_state->remove)
+ {
+ if (os->ind < os->argc)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+
+ SVN_ERR(svn_client_shelves_delete(shelf_name, local_abspath,
+ opt_state->dry_run,
+ ctx, pool));
+ if (! opt_state->quiet)
+ SVN_ERR(svn_cmdline_printf(pool, "deleted '%s'\n", shelf_name));
+ return SVN_NO_ERROR;
+ }
+
+ /* Parse the remaining arguments as paths. */
+ SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+ opt_state->targets,
+ ctx, FALSE, pool));
+
+ {
+ svn_depth_t depth = opt_state->depth;
+
+ /* shelve has no implicit dot-target `.', so don't you put that
+ code here! */
+ if (!targets->nelts)
+ return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+
+ SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
+
+ if (depth == svn_depth_unknown)
+ depth = svn_depth_infinity;
+
+ SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
+
+ SVN_ERR(svn_client_shelve(shelf_name,
+ targets, depth, opt_state->changelists,
+ opt_state->dry_run,
+ ctx, pool));
+ if (! opt_state->quiet)
+ SVN_ERR(svn_cmdline_printf(pool, "shelved '%s'\n", shelf_name));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__unshelve(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;
+ const char *shelf_name;
+ apr_array_header_t *targets;
+ const char *local_abspath;
+
+ SVN_ERR(get_shelf_name(&shelf_name, os, pool, pool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
+
+ /* There should be no remaining arguments. */
+ 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_ARG_PARSING_ERROR, 0, NULL);
+
+ if (opt_state->quiet)
+ ctx->notify_func2 = NULL; /* Easy out: avoid unneeded work */
+
+ SVN_ERR(svn_client_unshelve(shelf_name, local_abspath,
+ opt_state->keep_local, opt_state->dry_run,
+ ctx, pool));
+ if (! opt_state->quiet)
+ SVN_ERR(svn_cmdline_printf(pool, "unshelved '%s'\n", shelf_name));
+
+ return SVN_NO_ERROR;
+}
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__shelves(apr_getopt_t *os,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+ const char *local_abspath;
+
+ /* There should be no remaining arguments. */
+ if (os->ind < os->argc)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));
+ SVN_ERR(shelves_list(local_abspath, ctx, pool));
+
+ return SVN_NO_ERROR;
+}
Propchange: subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/shelve-checkpoint/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/subversion/svn/svn.c?rev=1801595&r1=1801594&r2=1801595&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/svn/svn.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/svn/svn.c Tue Jul 11 11:55:45 2017
@@ -143,7 +143,8 @@ typedef enum svn_cl__longopt_t {
opt_show_passwords,
opt_pin_externals,
opt_show_item,
- opt_adds_as_modification
+ opt_adds_as_modification,
+ opt_list
} svn_cl__longopt_t;
@@ -459,6 +460,12 @@ const apr_getopt_option_t svn_cl__option
" "
"resolve tree conflicts instead.")},
+ {"list", opt_list, 0, N_("list shelved patches")},
+
+ /* ### should have new option codes, and not be aliases */
+ {"keep", opt_keep_local, 0, N_("do not delete the shelved patch")},
+ {"delete", opt_remove, 0, N_("just delete the shelved patch")},
+
/* Long-opt Aliases
*
* These have NULL desriptions, but an option code that matches some
@@ -1631,6 +1638,28 @@ const svn_opt_subcommand_desc2_t svn_cl_
" the output of 'svn help merge' for 'undo'.\n"),
{opt_targets, 'R', opt_depth, 'q', opt_changelist} },
+ { "shelve", svn_cl__shelve, {0}, N_
+ ("Shelve changes.\n"
+ "usage: 1. shelve NAME PATH...\n"
+ " 2. shelve --delete NAME\n"
+ " 3. shelve --list\n"
+ "\n"
+ " 1. Shelve as NAME the local changes in the given PATHs.\n"
+ " 2. Delete the shelved patch NAME.\n"
+ " 3. List shelved patches.\n"),
+ {'q', opt_remove, opt_list, opt_dry_run,
+ 'N', opt_depth, opt_targets, opt_changelist} },
+
+ { "unshelve", svn_cl__unshelve, {0}, N_
+ ("Unshelve changes.\n"
+ "usage: unshelve [--keep] NAME\n"),
+ {'q', opt_keep_local, opt_dry_run} },
+
+ { "shelves", svn_cl__shelves, {0}, N_
+ ("List shelved patches.\n"
+ "usage: shelves\n"),
+ {} },
+
{ "status", svn_cl__status, {"stat", "st"}, N_
("Print the status of working copy files and directories.\n"
"usage: status [PATH...]\n"
@@ -2177,6 +2206,9 @@ sub_main(int *exit_code, int argc, const
case opt_dry_run:
opt_state.dry_run = TRUE;
break;
+ case opt_list:
+ opt_state.list = TRUE;
+ break;
case opt_revprop:
opt_state.revprop = TRUE;
break;
Modified: subversion/branches/shelve-checkpoint/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/shelve-checkpoint/tools/client-side/bash_completion?rev=1801595&r1=1801594&r2=1801595&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/tools/client-side/bash_completion (original)
+++ subversion/branches/shelve-checkpoint/tools/client-side/bash_completion Tue Jul 11 11:55:45 2017
@@ -248,6 +248,7 @@ _svn()
cmds="$cmds patch propdel pdel propedit pedit propget pget proplist"
cmds="$cmds plist propset pset relocate resolve resolved revert status"
cmds="$cmds switch unlock update upgrade"
+ cmds="$cmds shelve shelves unshelve"
# help options have a strange command status...
local helpOpts='--help -h'
@@ -264,6 +265,7 @@ _svn()
optsParam="$optsParam|--depth|--set-depth|--with-revprop"
optsParam="$optsParam|--cl|--changelist|--accept|--show-revs"
optsParam="$optsParam|--show-item"
+ optsParam="$optsParam|--name"
# svn:* and other (env SVN_BASH_*_PROPS) properties
local svnProps revProps allProps psCmds propCmds
@@ -1018,6 +1020,15 @@ _svn()
upgrade)
cmdOpts="$qOpts $pOpts"
;;
+ shelve)
+ cmdOpts="$qOpts --delete --list --dry-run $nOpts --targets $cOpts"
+ ;;
+ unshelve)
+ cmdOpts="$qOpts --keep --dry-run"
+ ;;
+ shelves)
+ cmdOpts="$qOpts"
+ ;;
*)
;;
esac