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));