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 2018/01/12 21:12:15 UTC
svn commit: r1821034 -
/subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c
Author: julianfoad
Date: Fri Jan 12 21:12:15 2018
New Revision: 1821034
URL: http://svn.apache.org/viewvc?rev=1821034&view=rev
Log:
On the 'shelve-checkpoint' branch: let 'shelve' say what it's going to do.
Modified:
subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c
Modified: 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=1821034&r1=1821033&r2=1821034&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c Fri Jan 12 21:12:15 2018
@@ -138,6 +138,11 @@ stats(svn_client_shelf_t *shelf,
const char *paths_str = "";
char *info_str;
+ if (version == 0)
+ {
+ return SVN_NO_ERROR;
+ }
+
SVN_ERR(svn_client_shelf_version_open(&shelf_version,
shelf, version,
scratch_pool, scratch_pool));
@@ -276,73 +281,42 @@ name_of_youngest(const char **name_p,
return SVN_NO_ERROR;
}
-/** Shelve/save a new version of changes.
- *
- * Shelve in shelf @a name the local modifications found by @a paths,
- * @a depth, @a changelists. Revert the shelved changes from the WC
- * unless @a keep_local is true.
- *
- * If no local modifications are found, throw an error.
- *
- * If @a dry_run is true, don't actually do it.
- *
- * Report in @a *new_version_p the new version number (or, with dry run,
- * what it would be).
+/*
+ * PATHS are relative to WC_ROOT_ABSPATH.
*/
static svn_error_t *
-shelve(int *new_version_p,
- const char *name,
- const apr_array_header_t *paths,
- svn_depth_t depth,
- const apr_array_header_t *changelists,
- svn_boolean_t keep_local,
- svn_boolean_t dry_run,
- const char *local_abspath,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
+run_status_on_wc_paths(const char *paths_base_abspath,
+ const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_client_status_func_t status_func,
+ void *status_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
{
- svn_client_shelf_t *shelf;
- int previous_version;
-
- SVN_ERR(svn_client_shelf_open(&shelf,
- name, local_abspath, ctx, scratch_pool));
- previous_version = shelf->max_version;
-
- SVN_ERR(svn_client_shelf_save_new_version(shelf,
- paths, depth, changelists,
- scratch_pool));
- if (shelf->max_version == previous_version)
- {
- SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("No local modifications found"));
- }
+ int i;
- if (!keep_local)
+ for (i = 0; i < paths->nelts; i++)
{
- svn_client_shelf_version_t *shelf_version;
-
- /* Reverse-apply the patch. This should be a safer way to remove those
- changes from the WC than running a 'revert' operation. */
- SVN_ERR(svn_client_shelf_version_open(&shelf_version,
- shelf, shelf->max_version,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_client_shelf_unapply(shelf_version,
- dry_run, scratch_pool));
- }
-
- SVN_ERR(svn_client_shelf_set_log_message(shelf, dry_run, scratch_pool));
+ const char *path = APR_ARRAY_IDX(paths, i, const char *);
+ const char *abspath = svn_path_join(paths_base_abspath, path,
+ scratch_pool);
- if (new_version_p)
- *new_version_p = shelf->max_version;
-
- if (dry_run)
- {
- SVN_ERR(svn_client_shelf_set_current_version(shelf, previous_version,
- scratch_pool));
+ SVN_ERR(svn_client_status6(NULL /*result_rev*/,
+ ctx, abspath,
+ NULL /*revision*/,
+ depth,
+ FALSE /*get_all*/,
+ FALSE /*check_out_of_date*/,
+ TRUE /*check_working_copy*/,
+ TRUE /*no_ignore*/,
+ TRUE /*ignore_externals*/,
+ FALSE /*depth_as_sticky*/,
+ changelists,
+ status_func, status_baton,
+ scratch_pool));
}
- SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
return SVN_NO_ERROR;
}
@@ -353,10 +327,9 @@ struct status_baton
const char *target_abspath;
const char *target_path;
- svn_boolean_t verbose; /* display all statuses while checking them */
- svn_boolean_t printed_header;
- svn_boolean_t *modified; /* set to TRUE when any modification is found */
-
+ const char *header;
+ svn_boolean_t quiet; /* don't display statuses while checking them */
+ svn_boolean_t modified; /* set to TRUE when any modification is found */
svn_client_ctx_t *ctx;
};
@@ -382,7 +355,7 @@ print_status(void *baton,
pool);
}
-/* Set *BATON to true if the reported path has any local modification or
+/* Set BATON->modified to true if TARGET has any local modification or
* any status that means we should not attempt to patch it.
*
* A callback of type svn_client_status_func_t. */
@@ -399,38 +372,144 @@ modification_checker(void *baton,
|| status->node_status == svn_wc_status_unversioned
|| status->node_status == svn_wc_status_normal))
{
- if (sb->verbose)
+ if (!sb->quiet)
{
- if (!sb->printed_header)
+ if (!sb->modified) /* print the header only once */
{
- SVN_ERR(svn_cmdline_printf(scratch_pool,
- _("--- Paths modified in shelf and in WC:\n")));
- sb->printed_header = TRUE;
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "%s", sb->header));
}
SVN_ERR(print_status(baton, target, status, scratch_pool));
}
- *sb->modified = TRUE;
+ sb->modified = TRUE;
+ }
+ return SVN_NO_ERROR;
+}
+
+/** Shelve/save a new version of changes.
+ *
+ * Shelve in shelf @a name the local modifications found by @a paths,
+ * @a depth, @a changelists. Revert the shelved changes from the WC
+ * unless @a keep_local is true.
+ *
+ * If no local modifications are found, throw an error.
+ *
+ * If @a dry_run is true, don't actually do it.
+ *
+ * Report in @a *new_version_p the new version number (or, with dry run,
+ * what it would be).
+ */
+static svn_error_t *
+shelve(int *new_version_p,
+ const char *name,
+ const apr_array_header_t *paths,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_boolean_t keep_local,
+ svn_boolean_t dry_run,
+ svn_boolean_t quiet,
+ const char *local_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ svn_client_shelf_t *shelf;
+ int previous_version;
+ const char *cwd_abspath;
+ struct status_baton sb;
+
+ SVN_ERR(svn_client_shelf_open(&shelf,
+ name, local_abspath, ctx, scratch_pool));
+ previous_version = shelf->max_version;
+
+ if (! quiet)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool, keep_local
+ ? _("--- Save a new version of '%s' in WC root '%s'\n")
+ : _("--- Shelve '%s' in WC root '%s'\n"),
+ shelf->name, shelf->wc_root_abspath));
+ SVN_ERR(stats(shelf, previous_version, apr_time_now(),
+ TRUE /*with_logmsg*/, scratch_pool));
+ }
+
+ sb.header = (keep_local
+ ? _("--- Modifications to save:\n")
+ : _("--- Modifications to shelve:\n"));
+ sb.quiet = quiet;
+ sb.modified = FALSE;
+ sb.ctx = ctx;
+ SVN_ERR(svn_dirent_get_absolute(&cwd_abspath, "", scratch_pool));
+ SVN_ERR(run_status_on_wc_paths(cwd_abspath, paths, depth, changelists,
+ modification_checker, &sb,
+ ctx, scratch_pool));
+
+ if (!sb.modified)
+ {
+ SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("No local modifications found"));
+ }
+
+ if (! quiet)
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ keep_local ? _("--- Saving...\n")
+ : _("--- Shelving...\n")));
+ SVN_ERR(svn_client_shelf_save_new_version(shelf,
+ paths, depth, changelists,
+ scratch_pool));
+ if (shelf->max_version == previous_version)
+ {
+ SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ keep_local ? _("None of the local modifications could be saved")
+ : _("None of the local modifications could be shelved"));
+ }
+
+ if (!keep_local)
+ {
+ svn_client_shelf_version_t *shelf_version;
+
+ /* Reverse-apply the patch. This should be a safer way to remove those
+ changes from the WC than running a 'revert' operation. */
+ SVN_ERR(svn_client_shelf_version_open(&shelf_version,
+ shelf, shelf->max_version,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_client_shelf_unapply(shelf_version,
+ dry_run, scratch_pool));
+ }
+
+ SVN_ERR(svn_client_shelf_set_log_message(shelf, dry_run, scratch_pool));
+
+ if (new_version_p)
+ *new_version_p = shelf->max_version;
+
+ if (dry_run)
+ {
+ SVN_ERR(svn_client_shelf_set_current_version(shelf, previous_version,
+ scratch_pool));
}
+
+ SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
return SVN_NO_ERROR;
}
/* Throw an error if any paths affected by SHELF:VERSION are currently
* modified in the WC. */
static svn_error_t *
-check_no_modified_paths(svn_client_shelf_version_t *shelf_version,
- svn_boolean_t verbose,
+check_no_modified_paths(const char *paths_base_abspath,
+ svn_client_shelf_version_t *shelf_version,
+ svn_boolean_t quiet,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
apr_hash_t *paths;
struct status_baton sb;
- svn_boolean_t any_modified = FALSE;
apr_hash_index_t *hi;
- sb.verbose = verbose;
- sb.printed_header = FALSE;
- sb.modified = &any_modified;
+ sb.target_abspath = shelf_version->shelf->wc_root_abspath;
+ sb.target_path = "";
+ sb.header = _("--- Paths modified in shelf and in WC:\n");
+ sb.quiet = quiet;
+ sb.modified = FALSE;
sb.ctx = ctx;
SVN_ERR(svn_client_shelf_get_paths(&paths, shelf_version,
@@ -438,11 +517,9 @@ check_no_modified_paths(svn_client_shelf
for (hi = apr_hash_first(scratch_pool, paths); hi; hi = apr_hash_next(hi))
{
const char *path = apr_hash_this_key(hi);
- const char *abspath = svn_path_join(shelf_version->shelf->wc_root_abspath,
- path, scratch_pool);
+ const char *abspath = svn_path_join(paths_base_abspath, path,
+ scratch_pool);
- sb.target_abspath = abspath;
- sb.target_path = abspath;
SVN_ERR(svn_client_status6(NULL /*result_rev*/,
ctx, abspath,
NULL /*revision*/,
@@ -457,7 +534,7 @@ check_no_modified_paths(svn_client_shelf
modification_checker, &sb,
scratch_pool));
}
- if (any_modified)
+ if (sb.modified)
{
return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
_("Cannot unshelve/restore, as at least one "
@@ -517,7 +594,8 @@ shelf_restore(const char *name,
SVN_ERR(svn_client_shelf_version_open(&shelf_version,
shelf, version,
scratch_pool, scratch_pool));
- SVN_ERR(check_no_modified_paths(shelf_version, !quiet, ctx, scratch_pool));
+ SVN_ERR(check_no_modified_paths(shelf->wc_root_abspath,
+ shelf_version, quiet, ctx, scratch_pool));
SVN_ERR(svn_client_shelf_apply(shelf_version,
dry_run, scratch_pool));
@@ -613,6 +691,7 @@ shelf_shelve(int *new_version,
apr_array_header_t *changelists,
svn_boolean_t keep_local,
svn_boolean_t dry_run,
+ svn_boolean_t quiet,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
{
@@ -634,7 +713,7 @@ shelf_shelve(int *new_version,
SVN_ERR(shelve(new_version, name,
targets, depth, changelists,
- keep_local, dry_run,
+ keep_local, dry_run, quiet,
local_abspath, ctx, scratch_pool));
return SVN_NO_ERROR;
@@ -684,7 +763,7 @@ svn_cl__shelve(apr_getopt_t *os,
err = shelf_shelve(&new_version, name,
targets, opt_state->depth, opt_state->changelists,
opt_state->keep_local, opt_state->dry_run,
- ctx, pool);
+ opt_state->quiet, ctx, pool);
if (ctx->log_msg_func3)
SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3,
err, pool));