Author: julianfoad
Date: Mon Jan 22 12:40:06 2018
New Revision: 1821855
URL: http://svn.apache.org/viewvc?rev=1821855&view=rev
Log:
Copy the main part of Shelving v2 (that is, with checkpointing) into trunk
from the 'shelve-checkpoint' branch.
Leave Shelving v1 active, add the new APIs, disable the new CLI using
'#ifdef SHELVING_V1', and don't update the tests and Bash-completion yet.
* subversion/include/svn_client.h
(svn_client_shelf_t,
svn_client_shelf_version_t,
svn_client_shelf_open,
svn_client_shelf_close,
svn_client_shelf_delete,
svn_client_shelf_save_new_version,
svn_client_shelf_set_current_version,
svn_client_shelf_version_open,
svn_client_shelf_apply,
svn_client_shelf_unapply,
svn_client_shelf_get_patch_abspath,
svn_client_shelf_export_patch,
svn_client_shelf_paths_changed,
svn_client_shelf_set_log_message,
svn_client_shelf_get_log_message,
svn_client_shelf_info_t,
svn_client_shelf_list): New.
* subversion/libsvn_client/client.h
(svn_client__shelf_revprop_set,
svn_client__shelf_revprop_get,
svn_client__shelf_revprop_list): New.
* subversion/libsvn_client/shelf.c
subversion/svn/shelf-cmd.c
New files.
* subversion/svn/cl.h
(svn_cl__shelf_diff,
svn_cl__shelf_drop,
svn_cl__shelf_list,
svn_cl__shelf_log,
svn_cl__shelf_save,
svn_cl__shelf_shelve,
svn_cl__shelf_unshelve): New declarations.
* subversion/svn/svn.c
(WITH_SHELVE_V1): New.
(svn_cl__options, svn_cl__cmd_table, sub_main):
Add the new CLI. Switch between old and new based on WITH_SHELVE_V1.
Added:
subversion/trunk/subversion/libsvn_client/shelf.c
- copied unchanged from r1821835,
subversion/branches/shelve-checkpoint/subversion/libsvn_client/shelf.c
subversion/trunk/subversion/svn/shelf-cmd.c
- copied unchanged from r1821835,
subversion/branches/shelve-checkpoint/subversion/svn/shelf-cmd.c
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/client.h
subversion/trunk/subversion/svn/cl.h
subversion/trunk/subversion/svn/svn.c
Modified: subversion/trunk/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1821855&r1=1821854&r2=1821855&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Mon Jan 22 12:40:06 2018
@@ -6715,7 +6715,244 @@ svn_client_cat(svn_stream_t *out,
-/** Shelving commands
+/** Shelving v2, with checkpoints
+ *
+ * @defgroup svn_client_shelves_checkpoints Shelves and checkpoints
+ * @{
+ */
+
+/** A shelf.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+typedef struct svn_client_shelf_t
+{
+ /* Public fields (read-only for public use) */
+ const char *name;
+ int max_version;
+
+ /* Private fields */
+ const char *wc_root_abspath;
+ const char *shelves_dir;
+ apr_hash_t *revprops;
+ svn_client_ctx_t *ctx;
+ apr_pool_t *pool;
+} svn_client_shelf_t;
+
+/** One version of a shelved change-set.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+typedef struct svn_client_shelf_version_t
+{
+ /* Public fields (read-only for public use) */
+ svn_client_shelf_t *shelf;
+ apr_time_t mtime; /** time-stamp of this version */
+
+ /* TODO: these should be Private fields */
+ const char *patch_abspath; /** abspath of the patch file */
+} svn_client_shelf_version_t;
+
+/** Open an existing shelf or create a new shelf.
+ *
+ * The shelf should be closed after use by calling svn_client_shelf_close().
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_open(svn_client_shelf_t **shelf_p,
+ const char *name,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool);
+
+/** Close @a shelf.
+ *
+ * If @a shelf is NULL, do nothing; otherwise @a shelf must be an open shelf.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_close(svn_client_shelf_t *shelf,
+ apr_pool_t *scratch_pool);
+
+/** Delete a shelf, by name.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_delete(const char *name,
+ const char *local_abspath,
+ svn_boolean_t dry_run,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/** Save the local modifications found by @a paths, @a depth,
+ * @a changelists as a new version of @a shelf.
+ *
+ * If there are no local modifications in the specified locations, do not
+ * create a new version of @a shelf.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_save_new_version(svn_client_shelf_t *shelf,
+ const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ apr_pool_t *scratch_pool);
+
+/** Set the newest version of @a shelf to @a version.
+ *
+ * Delete all newer versions.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_set_current_version(svn_client_shelf_t *shelf,
+ int version,
+ apr_pool_t *scratch_pool);
+
+/** Open an existing shelf version.
+ *
+ * There is no need to "close" it after use.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_version_open(svn_client_shelf_version_t **shelf_version_p,
+ svn_client_shelf_t *shelf,
+ int version,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Apply version @a version of @a shelf to the WC.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_apply(svn_client_shelf_version_t *shelf_version,
+ svn_boolean_t dry_run,
+ apr_pool_t *scratch_pool);
+
+/** Reverse-apply the current version of @a shelf to the WC.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_unapply(svn_client_shelf_version_t *shelf_version,
+ svn_boolean_t dry_run,
+ apr_pool_t *scratch_pool);
+
+/** Set @a *patch_abspath to the patch file path of @a shelf_version.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_get_patch_abspath(char **patch_abspath,
+ svn_client_shelf_version_t *shelf_version,
+ apr_pool_t *scratch_pool);
+
+/** Output version @a version of @a shelf as a patch to @a outstream.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_export_patch(svn_client_shelf_version_t *shelf_version,
+ svn_stream_t *outstream,
+ apr_pool_t *scratch_pool);
+
+/** Set @a *affected_paths to a hash with one entry for each path affected
+ * by the @a shelf @a version. The hash key is the old path and value is
+ * the new path, both relative to the WC root. The key and value are the
+ * same except when a path is moved or copied.
+ *
+ * @since New in 1.10, changed in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_paths_changed(apr_hash_t **affected_paths,
+ svn_client_shelf_version_t *shelf_version,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Set the log message in @a shelf, using the log message callbacks in
+ * the client context.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_set_log_message(svn_client_shelf_t *shelf,
+ svn_boolean_t dry_run,
+ apr_pool_t *scratch_pool);
+
+/** Get the log message in @a shelf into @a *log_message.
+ *
+ * Set @a *log_message to NULL if there is no log message.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_get_log_message(char **log_message,
+ svn_client_shelf_t *shelf,
+ apr_pool_t *result_pool);
+
+/** Information about a shelf.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+typedef struct svn_client_shelf_info_t
+{
+ apr_time_t mtime; /* mtime of the latest change */
+} svn_client_shelf_info_t;
+
+/** Set @a *shelved_patch_infos to a hash, keyed by shelf name, of pointers to
+ * @c svn_client_shelf_info_t structures.
+ *
+ * @a local_abspath is any path in the WC and is used to find the WC root.
+ *
+ * @since New in 1.X.
+ * @warning EXPERIMENTAL.
+ */
+SVN_EXPERIMENTAL
+svn_error_t *
+svn_client_shelf_list(apr_hash_t **shelf_infos,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** @} */
+
+/** Shelving v1
*
* @defgroup svn_client_shelve_funcs Client Shelving Functions
* @{
Modified: subversion/trunk/subversion/libsvn_client/client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1821855&r1=1821854&r2=1821855&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Mon Jan 22 12:40:06 2018
@@ -1267,6 +1267,39 @@ svn_client__merge_locked(svn_client__con
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/** Set @a shelf's revprop @a prop_name to @a prop_val.
+ *
+ * If @a prop_val is NULL, delete the property (if present).
+ */
+svn_error_t *
+svn_client__shelf_revprop_set(svn_client_shelf_t *shelf,
+ const char *prop_name,
+ const svn_string_t *prop_val,
+ apr_pool_t *scratch_pool);
+
+/** Get @a shelf's revprop @a prop_name into @a *prop_val.
+ *
+ * If the property is not present, set @a *prop_val to NULL.
+ *
+ * The lifetime of the result is limited to that of @a shelf and/or
+ * of @a result_pool.
+ */
+svn_error_t *
+svn_client__shelf_revprop_get(svn_string_t **prop_val,
+ svn_client_shelf_t *shelf,
+ const char *prop_name,
+ apr_pool_t *result_pool);
+
+/** Get @a shelf's revprops into @a props.
+ *
+ * The lifetime of the result is limited to that of @a shelf and/or
+ * of @a result_pool.
+ */
+svn_error_t *
+svn_client__shelf_revprop_list(apr_hash_t **props,
+ svn_client_shelf_t *shelf,
+ apr_pool_t *result_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/trunk/subversion/svn/cl.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1821855&r1=1821854&r2=1821855&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Mon Jan 22 12:40:06 2018
@@ -304,6 +304,13 @@ svn_opt_subcommand_t
svn_cl__revert,
svn_cl__resolve,
svn_cl__resolved,
+ svn_cl__shelf_diff,
+ svn_cl__shelf_drop,
+ svn_cl__shelf_list,
+ svn_cl__shelf_log,
+ svn_cl__shelf_save,
+ svn_cl__shelf_shelve,
+ svn_cl__shelf_unshelve,
svn_cl__shelve,
svn_cl__unshelve,
svn_cl__shelves,
Modified: subversion/trunk/subversion/svn/svn.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1821855&r1=1821854&r2=1821855&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Mon Jan 22 12:40:06 2018
@@ -61,6 +61,8 @@
#include "svn_private_config.h"
+#define WITH_SHELVE_V1
+
/*** Option Processing ***/
/* Add an identifier here for long options that don't have a short
@@ -474,9 +476,11 @@ const apr_getopt_option_t svn_cl__option
{"vacuum-pristines", opt_vacuum_pristines, 0,
N_("remove unreferenced pristines from .svn
directory")},
+#ifdef WITH_SHELVE_V1
{"list", opt_list, 0, N_("list shelved patches")},
{"keep-shelved", opt_keep_shelved, 0, N_("do not delete the shelved patch")},
{"delete", opt_delete, 0, N_("delete the shelved patch")},
+#endif
/* Long-opt Aliases
*
@@ -1690,6 +1694,119 @@ 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} },
+#ifndef WITH_SHELVE_V1
+ { "shelf-diff", svn_cl__shelf_diff, {0}, N_
+ ("Show shelved changes as a diff.\n"
+ "usage: shelf-diff NAME [VERSION]\n"
+ "\n"
+ " Show the changes in shelf NAME:VERSION (default: latest) as a diff.\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ },
+
+ { "shelf-drop", svn_cl__shelf_drop, {0}, N_
+ ("Delete a shelf.\n"
+ "usage: shelf-drop NAME\n"
+ "\n"
+ " Delete the shelf named NAME.\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ },
+
+ { "shelf-list", svn_cl__shelf_list, {"shelves"}, N_
+ ("List shelves.\n"
+ "usage: shelf-list\n"
+ "\n"
+ " List shelves. Include the first line of any log message\n"
+ " and some details about the contents of the shelf, unless '-q' is\n"
+ " given.\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ {'q'}
+ },
+
+ { "shelf-log", svn_cl__shelf_log, {0}, N_
+ ("Show the versions of a shelf.\n"
+ "usage: shelf-log NAME\n"
+ "\n"
+ " Show all versions of shelf NAME.\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ {'q'}
+ },
+
+ { "shelf-save", svn_cl__shelf_save, {0}, N_
+ ("Copy local changes onto a new version of a shelf.\n"
+ "usage: shelf-log NAME\n"
+ "\n"
+ " Save local changes in the given PATHs as a new version of shelf
NAME.\n"
+ " A new log message can be given with -m, -F, etc.\n"
+ "\n"
+ " The same as 'svn shelve --keep-local'.\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ {'q', opt_dry_run,
+ opt_depth, opt_targets, opt_changelist,
+ /* almost SVN_CL__LOG_MSG_OPTIONS but not currently opt_with_revprop: */
+ 'm', 'F', opt_force_log, opt_editor_cmd, opt_encoding,
+ }
+ },
+
+ { "shelve", svn_cl__shelf_shelve, {0}, N_
+ ("Move local changes onto a shelf.\n"
+ "usage: shelve [--keep-local] NAME [PATH...]\n"
+ "\n"
+ " Save the local changes in the given PATHs to a shelf named NAME.\n"
+ " Revert those changes from the WC unless '--keep-local' is given.\n"
+ " If a log message is given with '-m' or '-F', replace the shelf's\n"
+ " current log message (if any).\n"
+ "\n"
+ " 'svn shelve --keep-local' is the same as 'svn shelf-save'.\n"
+ "\n"
+ " The kinds of change you can shelve are those supported by 'svn diff'\n"
+ " and 'svn patch'. The following are currently NOT supported:\n"
+ " mergeinfo changes, copies, moves, mkdir, rmdir,\n"
+ " 'binary' content, uncommittable states\n"
+ "\n"
+ " To bring back shelved changes, use 'svn unshelve NAME'.\n"
+ "\n"
+ " Shelves are stored in <WC>/.svn/shelves/\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ {'q', opt_dry_run, opt_keep_local,
+ opt_depth, opt_targets, opt_changelist,
+ /* almost SVN_CL__LOG_MSG_OPTIONS but not currently opt_with_revprop: */
+ 'm', 'F', opt_force_log, opt_editor_cmd, opt_encoding,
+ } },
+
+ { "unshelve", svn_cl__shelf_unshelve, {0}, N_
+ ("Copy shelved changes back into the WC.\n"
+ "usage: unshelve [NAME [VERSION]]\n"
+ "\n"
+ " Apply the shelf named NAME to the working copy.\n"
+ " NAME defaults to the newest shelf.\n"
+ "\n"
+ " Any conflict between the change being unshelved and a change\n"
+ " already in the WC is handled the same way as by 'svn patch',\n"
+ " creating a 'reject' file.\n"
+ "\n"
+ " The shelving feature is EXPERIMENTAL. This command is likely to
change\n"
+ " in the next release, and there is no promise of backward
compatibility.\n"
+ ),
+ {'q', opt_dry_run} },
+#else
{ "shelve", svn_cl__shelve, {0}, N_
("Put a local change aside, as if putting it on a shelf.\n"
"usage: 1. shelve [--keep-local] NAME [PATH...]\n"
@@ -1757,6 +1874,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
" in the next release, and there is no promise of backward
compatibility.\n"
),
{'q'} },
+#endif
{ "status", svn_cl__status, {"stat", "st"}, N_
("Print the status of working copy files and directories.\n"
@@ -3024,7 +3142,13 @@ sub_main(int *exit_code, int argc, const
|| subcommand->cmd_func == svn_cl__move
|| subcommand->cmd_func == svn_cl__lock
|| subcommand->cmd_func == svn_cl__propedit
- || subcommand->cmd_func == svn_cl__shelve))
+#ifndef WITH_SHELVE_V1
+ || subcommand->cmd_func == svn_cl__shelf_save
+ || subcommand->cmd_func == svn_cl__shelf_shelve
+#else
+ || subcommand->cmd_func == svn_cl__shelve
+#endif
+ ))
{
/* If the -F argument is a file that's under revision control,
that's probably not what the user intended. */