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/11/09 15:28:26 UTC

svn commit: r1846252 - in /subversion/trunk/subversion: include/private/svn_client_private.h libsvn_client/commit.c

Author: julianfoad
Date: Fri Nov  9 15:28:25 2018
New Revision: 1846252

URL: http://svn.apache.org/viewvc?rev=1846252&view=rev
Log:
Introduce 'svn_client__wc_replay' API.

* subversion/include/private/svn_client_private.h
  (svn_client__wc_replay): New.

* subversion/libsvn_client/commit.c
  (svn_client__wc_replay): New.
  (harvest_committables): New, factored out...
  (svn_client_commit6): ... from here.

Modified:
    subversion/trunk/subversion/include/private/svn_client_private.h
    subversion/trunk/subversion/libsvn_client/commit.c

Modified: subversion/trunk/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_client_private.h?rev=1846252&r1=1846251&r2=1846252&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_client_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_client_private.h Fri Nov  9 15:28:25 2018
@@ -412,6 +412,36 @@ svn_client__get_diff_summarize_callbacks
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
+/** Send committable changes found in the WC to a delta-editor.
+ *
+ * Committable changes are found in TARGETS:DEPTH:CHANGELISTS.
+ *
+ * Send the changes to EDITOR:EDIT_BATON.
+ *
+ * Compared with svn_client__do_commit(), this (like svn_client_commit6)
+ * handles:
+ *  - condense targets and find committable paths
+ *  - checking only one repository is involved
+ *
+ * Compared with svn_client_commit6(), this does not handle:
+ *  - externals
+ *  - log message
+ *  - revprops
+ *  - checking the commit includes both halves of each local move
+ *  - changing the copy revision of each local move to ~HEAD
+ *  - WC write locks
+ *  - bumping revisions in WC
+ *  - removing locks and changelists in WC
+ */
+svn_error_t *
+svn_client__wc_replay(const apr_array_header_t *targets,
+                      svn_depth_t depth,
+                      const apr_array_header_t *changelists,
+                      const svn_delta_editor_t *editor,
+                      void *edit_baton,
+                      svn_client_ctx_t *ctx,
+                      apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/trunk/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit.c?rev=1846252&r1=1846251&r2=1846252&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit.c Fri Nov  9 15:28:25 2018
@@ -500,6 +500,110 @@ append_externals_as_explicit_targets(apr
   return SVN_NO_ERROR;
 }
 
+/* Crawl the working copy for commit items.
+ */
+static svn_error_t *
+harvest_committables(apr_array_header_t **commit_items_p,
+                     apr_hash_t **committables_by_path_p,
+                     apr_hash_t **lock_tokens,
+                     const char *base_dir_abspath,
+                     const apr_array_header_t *targets,
+                     int depth_empty_start,
+                     svn_depth_t depth,
+                     svn_boolean_t just_locked,
+                     const apr_array_header_t *changelists,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  struct check_url_kind_baton cukb;
+  svn_client__committables_t *committables;
+  apr_hash_index_t *hi;
+
+  /* Prepare for when we have a copy containing not-present nodes. */
+  cukb.pool = scratch_pool;
+  cukb.session = NULL; /* ### Can we somehow reuse session? */
+  cukb.repos_root_url = NULL;
+  cukb.ctx = ctx;
+
+  SVN_ERR(svn_client__harvest_committables(&committables, lock_tokens,
+                                           base_dir_abspath, targets,
+                                           depth_empty_start, depth,
+                                           just_locked,
+                                           changelists,
+                                           check_url_kind, &cukb,
+                                           ctx, result_pool, scratch_pool));
+  if (apr_hash_count(committables->by_repository) == 0)
+    {
+      *commit_items_p = NULL;
+      return SVN_NO_ERROR;  /* Nothing to do */
+    }
+  else if (apr_hash_count(committables->by_repository) > 1)
+    {
+      return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+          _("Commit can only commit to a single repository at a time.\n"
+            "Are all targets part of the same working copy?"));
+    }
+
+  hi = apr_hash_first(scratch_pool, committables->by_repository);
+  *commit_items_p = apr_hash_this_val(hi);
+  if (committables_by_path_p)
+    *committables_by_path_p = committables->by_path;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client__wc_replay(const apr_array_header_t *targets,
+                      svn_depth_t depth,
+                      const apr_array_header_t *changelists,
+                      const svn_delta_editor_t *editor,
+                      void *edit_baton,
+                      svn_client_ctx_t *ctx,
+                      apr_pool_t *pool)
+{
+  const char *base_abspath;
+  apr_array_header_t *rel_targets;
+  apr_hash_t *lock_tokens;
+  apr_array_header_t *commit_items;
+  const char *base_url;
+
+  /* Condense the target list. This makes all targets absolute. */
+  SVN_ERR(svn_dirent_condense_targets(&base_abspath, &rel_targets, targets,
+                                      FALSE, pool, pool));
+
+  /* No targets means nothing to commit, so just return. */
+  if (base_abspath == NULL)
+    return SVN_NO_ERROR;
+
+  SVN_ERR_ASSERT(rel_targets != NULL);
+
+  /* If we calculated only a base and no relative targets, this
+     must mean that we are being asked to commit (effectively) a
+     single path. */
+  if (rel_targets->nelts == 0)
+    APR_ARRAY_PUSH(rel_targets, const char *) = "";
+
+  /* Crawl the working copy for commit items. */
+  SVN_ERR(harvest_committables(&commit_items, NULL /*committables_by_path_p*/,
+                               &lock_tokens,
+                               base_abspath, rel_targets,
+                               -1 /*depth_empty_start*/,
+                               depth,
+                               FALSE /*just_locked*/,
+                               changelists,
+                               ctx, pool, pool));
+
+  /* Sort and condense our COMMIT_ITEMS. */
+  SVN_ERR(svn_client__condense_commit_items(&base_url, commit_items, pool));
+
+  ctx->notify_func2 = NULL;
+  SVN_ERR(svn_client__do_commit(base_url, commit_items,
+                                editor, edit_baton,
+                                NULL /*notify_prefix*/, NULL /*sha1_checksums*/,
+                                ctx, pool, pool));
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_client_commit6(const apr_array_header_t *targets,
                    svn_depth_t depth,
@@ -525,7 +629,7 @@ svn_client_commit6(const apr_array_heade
   apr_array_header_t *rel_targets;
   apr_array_header_t *lock_targets;
   apr_array_header_t *locks_obtained;
-  svn_client__committables_t *committables;
+  apr_hash_t *committables_by_path;
   apr_hash_t *lock_tokens;
   apr_hash_t *sha1_checksums;
   apr_array_header_t *commit_items;
@@ -615,55 +719,27 @@ svn_client_commit6(const apr_array_heade
                                                   pool);
 
   /* Crawl the working copy for commit items. */
-  {
-    struct check_url_kind_baton cukb;
-
-    /* Prepare for when we have a copy containing not-present nodes. */
-    cukb.pool = iterpool;
-    cukb.session = NULL; /* ### Can we somehow reuse session? */
-    cukb.repos_root_url = NULL;
-    cukb.ctx = ctx;
-
-    cmt_err = svn_error_trace(
-                   svn_client__harvest_committables(&committables,
-                                                    &lock_tokens,
-                                                    base_abspath,
-                                                    rel_targets,
-                                                    depth_empty_after,
-                                                    depth,
-                                                    ! keep_locks,
-                                                    changelists,
-                                                    check_url_kind,
-                                                    &cukb,
-                                                    ctx,
-                                                    pool,
-                                                    iterpool));
-
-    svn_pool_clear(iterpool);
-  }
+  cmt_err = svn_error_trace(
+              harvest_committables(&commit_items, &committables_by_path,
+                                   &lock_tokens,
+                                   base_abspath,
+                                   rel_targets,
+                                   depth_empty_after,
+                                   depth,
+                                   ! keep_locks,
+                                   changelists,
+                                   ctx,
+                                   pool,
+                                   iterpool));
+  svn_pool_clear(iterpool);
 
   if (cmt_err)
     goto cleanup;
 
-  if (apr_hash_count(committables->by_repository) == 0)
+  if (!commit_items)
     {
       goto cleanup; /* Nothing to do */
     }
-  else if (apr_hash_count(committables->by_repository) > 1)
-    {
-      cmt_err = svn_error_create(
-             SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-             _("Commit can only commit to a single repository at a time.\n"
-               "Are all targets part of the same working copy?"));
-      goto cleanup;
-    }
-
-  {
-    apr_hash_index_t *hi = apr_hash_first(iterpool,
-                                          committables->by_repository);
-
-    commit_items = apr_hash_this_val(hi);
-  }
 
   /* If our array of targets contains only locks (and no actual file
      or prop modifications), then we return here to avoid committing a
@@ -713,7 +789,7 @@ svn_client_commit6(const apr_array_heade
           if (moved_from_abspath && delete_op_root_abspath)
             {
               svn_client_commit_item3_t *delete_half =
-                svn_hash_gets(committables->by_path, delete_op_root_abspath);
+                svn_hash_gets(committables_by_path, delete_op_root_abspath);
 
               if (!delete_half)
                 {
@@ -769,7 +845,7 @@ svn_client_commit6(const apr_array_heade
 
           if (moved_to_abspath && copy_op_root_abspath &&
               strcmp(moved_to_abspath, copy_op_root_abspath) == 0 &&
-              svn_hash_gets(committables->by_path, copy_op_root_abspath)
+              svn_hash_gets(committables_by_path, copy_op_root_abspath)
               == NULL)
             {
               cmt_err = svn_error_createf(