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/12/07 13:33:07 UTC
svn commit: r1817370 -
/subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c
Author: julianfoad
Date: Thu Dec 7 13:33:07 2017
New Revision: 1817370
URL: http://svn.apache.org/viewvc?rev=1817370&view=rev
Log:
On the 'shelve-checkpoint' branch: Bail out if unshelving would affect a path
that is already modified in the WC.
* subversion/svn/shelve-cmd.c
(modification_checker,
check_no_modified_paths): New.
(restore): Check for modified paths before restoring.
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=1817370&r1=1817369&r2=1817370&view=diff
==============================================================================
--- subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c (original)
+++ subversion/branches/shelve-checkpoint/subversion/svn/shelve-cmd.c Thu Dec 7 13:33:07 2017
@@ -293,6 +293,71 @@ shelve(int *new_version_p,
return SVN_NO_ERROR;
}
+/* Set *BATON to true if the reported path 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. */
+static svn_error_t *
+modification_checker(void *baton,
+ const char *target,
+ const svn_client_status_t *status,
+ apr_pool_t *scratch_pool)
+{
+ svn_boolean_t *modified = baton;
+
+ if (status->conflicted
+ || ! (status->node_status == svn_wc_status_none
+ || status->node_status == svn_wc_status_unversioned
+ || status->node_status == svn_wc_status_normal))
+ {
+ *modified = TRUE;
+ }
+ 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_t *shelf,
+ int version,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *paths;
+ apr_hash_index_t *hi;
+
+ SVN_ERR(svn_client_shelf_get_paths(&paths,
+ shelf, version,
+ scratch_pool, scratch_pool));
+ 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->wc_root_abspath, path, scratch_pool);
+ svn_boolean_t modified = FALSE;
+
+ SVN_ERR(svn_client_status6(NULL /*result_rev*/,
+ ctx, abspath,
+ NULL /*revision*/,
+ svn_depth_empty,
+ FALSE /*get_all*/,
+ FALSE /*check_out_of_date*/,
+ TRUE /*check_working_copy*/,
+ TRUE /*no_ignore*/,
+ TRUE /*ignore_externals*/,
+ FALSE /*depth_as_sticky*/,
+ NULL /*changelists*/,
+ modification_checker, &modified,
+ scratch_pool));
+ if (modified)
+ {
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Shelf affects at least one path that is already modified: '%s'"),
+ path);
+ }
+ }
+ return SVN_NO_ERROR;
+}
+
/** Restore/unshelve a given or newest version of changes.
*
* Restore local modifications from shelf @a name version @a arg,
@@ -331,6 +396,8 @@ restore(const char *name,
version = shelf->max_version;
}
+ SVN_ERR(check_no_modified_paths(shelf, version, ctx, scratch_pool));
+
SVN_ERR(svn_client_shelf_apply(shelf, version,
dry_run, scratch_pool));