You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/09/30 11:01:21 UTC

svn commit: r1762881 - in /subversion/branches/resolve-incoming-add/subversion: include/private/svn_wc_private.h libsvn_client/conflicts.c libsvn_wc/conflicts.c libsvn_wc/wc_db.h libsvn_wc/wc_db_merge_incoming_add.c

Author: stsp
Date: Fri Sep 30 11:01:20 2016
New Revision: 1762881

URL: http://svn.apache.org/viewvc?rev=1762881&view=rev
Log:
On the 'resolve-incoming-add' branch, move the diff processor out
of libsvn_wc/wc_db into libsvn_client.

As Bert Huijben points out, it is impossible to hold a WC transation open
while talking to the server. So we'll add things to the working copy
bit by bit, and risk an incomplete merge upon error or cancellation.
This matches standard 'svn merge' behaviour.

* subversion/include/private/svn_wc_private.h
  (svn_wc__get_merge_incoming_add_diff_processor): Remove.

* subversion/libsvn_client/conflicts.c
  (merge_newly_added_dir_baton): Moved here from libsvn_wc.
  (diff_dir_added, diff_dir_changed, diff_dir_deleted,
   diff_file_added, diff_file_changed, diff_file_deleted): Same.
  (merge_newly_added_dir): Construct the diff processor directly.

* subversion/libsvn_wc/conflicts.c
  (svn_wc__get_merge_incoming_add_diff_processor): Remove.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_get_merge_incoming_add_diff_processor): Remove.

* subversion/libsvn_wc/wc_db_merge_incoming_add.c: Remove this file.

Removed:
    subversion/branches/resolve-incoming-add/subversion/libsvn_wc/wc_db_merge_incoming_add.c
Modified:
    subversion/branches/resolve-incoming-add/subversion/include/private/svn_wc_private.h
    subversion/branches/resolve-incoming-add/subversion/libsvn_client/conflicts.c
    subversion/branches/resolve-incoming-add/subversion/libsvn_wc/conflicts.c
    subversion/branches/resolve-incoming-add/subversion/libsvn_wc/wc_db.h

Modified: subversion/branches/resolve-incoming-add/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/resolve-incoming-add/subversion/include/private/svn_wc_private.h?rev=1762881&r1=1762880&r2=1762881&view=diff
==============================================================================
--- subversion/branches/resolve-incoming-add/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/resolve-incoming-add/subversion/include/private/svn_wc_private.h Fri Sep 30 11:01:20 2016
@@ -2046,17 +2046,6 @@ svn_wc__read_conflict_descriptions2_t(co
                                       apr_pool_t *result_pool,
                                       apr_pool_t *scratch_pool);
 
-svn_error_t *
-svn_wc__get_merge_incoming_add_diff_processor(
-  const svn_diff_tree_processor_t **diff_processor,
-  void **diff_processor_baton,
-  const char *target_abspath,
-  const char *prefix_relpath,
-  svn_boolean_t reverse_merge,
-  svn_wc_context_t *wc_ctx,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/resolve-incoming-add/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/resolve-incoming-add/subversion/libsvn_client/conflicts.c?rev=1762881&r1=1762880&r2=1762881&view=diff
==============================================================================
--- subversion/branches/resolve-incoming-add/subversion/libsvn_client/conflicts.c (original)
+++ subversion/branches/resolve-incoming-add/subversion/libsvn_client/conflicts.c Fri Sep 30 11:01:20 2016
@@ -5496,6 +5496,169 @@ unlock_wc:
   return SVN_NO_ERROR;
 }
 
+struct merge_newly_added_dir_baton {
+  const char *target_abspath;
+  svn_client_ctx_t *ctx;
+};
+
+/* An svn_diff_tree_processor_t callback. */
+static svn_error_t *
+diff_dir_added(const char *relpath,
+               const svn_diff_source_t *copyfrom_source,
+               const svn_diff_source_t *right_source,
+               apr_hash_t *copyfrom_props,
+               apr_hash_t *right_props,
+               void *dir_baton,
+               const struct svn_diff_tree_processor_t *processor,
+               apr_pool_t *scratch_pool)
+{
+  struct merge_newly_added_dir_baton *b = processor->baton;
+
+  SVN_DBG(("%s: %s\n", __func__, relpath));
+  if (copyfrom_source)
+    SVN_DBG(("%s: copyfrom source: %s@%lu\n", __func__,
+      copyfrom_source->repos_relpath, copyfrom_source->revision));
+  SVN_DBG(("%s: right source: %s@%lu\n", __func__,
+    right_source->repos_relpath, right_source->revision));
+
+  return SVN_NO_ERROR;
+}
+
+/* An svn_wc_diff_callbacks4_t function. */
+static svn_error_t *
+diff_dir_changed(const char *relpath,
+                 const svn_diff_source_t *left_source,
+                 const svn_diff_source_t *right_source,
+                 apr_hash_t *left_props,
+                 apr_hash_t *right_props,
+                 const apr_array_header_t *prop_changes,
+                 void *dir_baton,
+                 const struct svn_diff_tree_processor_t *processor,
+                 apr_pool_t *scratch_pool)
+{
+  struct merge_newly_added_dir_baton *b = processor->baton;
+
+  SVN_DBG(("%s: %s\n", __func__, relpath));
+  SVN_DBG(("%s: left source: %s@%lu\n", __func__,
+    left_source->repos_relpath, left_source->revision));
+  SVN_DBG(("%s: right source: %s@%lu\n", __func__,
+    right_source->repos_relpath, right_source->revision));
+
+  return SVN_NO_ERROR;
+}
+
+/* An svn_diff_tree_processor_t callback. */
+static svn_error_t *
+diff_dir_deleted(const char *relpath,
+                 const svn_diff_source_t *left_source,
+                 apr_hash_t *left_props,
+                 void *dir_baton,
+                 const struct svn_diff_tree_processor_t *processor,
+                 apr_pool_t *scratch_pool)
+{
+  struct merge_newly_added_dir_baton *b = processor->baton;
+
+  SVN_DBG(("%s: %s\n", __func__, relpath));
+  SVN_DBG(("%s: left source: %s@%lu\n", __func__,
+    left_source->repos_relpath, left_source->revision));
+
+  return SVN_NO_ERROR;
+}
+
+/* An svn_diff_tree_processor_t callback. */
+static svn_error_t *
+diff_file_added(const char *relpath,
+                const svn_diff_source_t *copyfrom_source,
+                const svn_diff_source_t *right_source,
+                const char *copyfrom_file,
+                const char *right_file,
+                apr_hash_t *copyfrom_props,
+                apr_hash_t *right_props,
+                void *file_baton,
+                const struct svn_diff_tree_processor_t *processor,
+                apr_pool_t *scratch_pool)
+{
+  struct merge_newly_added_dir_baton *b = processor->baton;
+  const char *local_abspath;
+  svn_node_kind_t on_disk_kind;
+  svn_node_kind_t db_kind;
+
+  local_abspath = svn_dirent_join(b->target_abspath, relpath, scratch_pool);
+
+  SVN_ERR(svn_io_check_path(local_abspath, &on_disk_kind, scratch_pool));
+
+  if (on_disk_kind != svn_node_none)
+    {
+      SVN_DBG(("%s: obstructed: %s\n", __func__, local_abspath));
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(svn_wc_read_kind2(&db_kind, b->ctx->wc_ctx, local_abspath,
+                            FALSE, FALSE, scratch_pool));
+  if (db_kind != svn_node_none && db_kind != svn_node_unknown)
+    {
+      SVN_DBG(("%s: tree conflict: %s\n", __func__, local_abspath));
+      return SVN_NO_ERROR;
+    }
+
+  SVN_DBG(("%s: %s (%s: %s)\n", __func__, relpath,
+      svn_node_kind_to_word(on_disk_kind), local_abspath));
+  if (copyfrom_source)
+    SVN_DBG(("%s: copyfrom source: %s@%lu\n", __func__,
+      copyfrom_source->repos_relpath, copyfrom_source->revision));
+  SVN_DBG(("%s: right source: %s@%lu\n", __func__,
+    right_source->repos_relpath, right_source->revision));
+  SVN_DBG(("%s: right file: %s\n", __func__, right_file));
+
+  return SVN_NO_ERROR;
+}
+
+/* An svn_diff_tree_processor_t callback. */
+static svn_error_t *
+diff_file_changed(const char *relpath,
+                  const svn_diff_source_t *left_source,
+                  const svn_diff_source_t *right_source,
+                  const char *left_file,
+                  const char *right_file,
+                  apr_hash_t *left_props,
+                  apr_hash_t *right_props,
+                  svn_boolean_t file_modified,
+                  const apr_array_header_t *prop_changes,
+                  void *file_baton,
+                  const struct svn_diff_tree_processor_t *processor,
+                  apr_pool_t *scratch_pool)
+{
+  struct merge_newly_added_dir_baton *b = processor->baton;
+
+  SVN_DBG(("%s: %s\n", __func__, relpath));
+  SVN_DBG(("%s: left source: %s@%lu\n", __func__,
+    left_source->repos_relpath, left_source->revision));
+  SVN_DBG(("%s: right source: %s@%lu\n", __func__,
+    right_source->repos_relpath, right_source->revision));
+  SVN_DBG(("%s: right file: %s\n", __func__, right_file));
+
+  return SVN_NO_ERROR;
+}
+
+/* An svn_diff_tree_processor_t callback. */
+static svn_error_t *
+diff_file_deleted(const char *relpath,
+                  const svn_diff_source_t *left_source,
+                  const char *left_file,
+                  apr_hash_t *left_props,
+                  void *file_baton,
+                  const struct svn_diff_tree_processor_t *processor,
+                  apr_pool_t *scratch_pool)
+{
+  struct merge_newly_added_dir_baton *b = processor->baton;
+
+  SVN_DBG(("%s: %s\n", __func__, relpath));
+  SVN_DBG(("%s: left source: %s@%lu\n", __func__,
+    left_source->repos_relpath, left_source->revision));
+
+  return SVN_NO_ERROR;
+}
+
 /* Merge a newly added directory into TARGET_ABSPATH in the working copy.
  *
  * This uses a diff-tree processor because our standard merge operation
@@ -5518,8 +5681,9 @@ merge_newly_added_dir(svn_client__confli
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
 {
+  svn_diff_tree_processor_t *processor;
+  struct merge_newly_added_dir_baton baton;
   const svn_diff_tree_processor_t *diff_processor;
-  void *diff_processor_baton;
   svn_ra_session_t *ra_session;
   const char *corrected_url;
   svn_ra_session_t *extra_ra_session;
@@ -5535,10 +5699,27 @@ merge_newly_added_dir(svn_client__confli
   svn_uri_split(&anchor1, &target1, source1, scratch_pool);
   svn_uri_split(&anchor2, &target2, source2, scratch_pool);
 
-  SVN_ERR(svn_wc__get_merge_incoming_add_diff_processor(
-            &diff_processor, &diff_processor_baton,
-            target_abspath, target1, reverse_merge, ctx->wc_ctx,
-            scratch_pool, scratch_pool));
+  baton.target_abspath = target_abspath;
+  baton.ctx = ctx;
+
+  processor = svn_diff__tree_processor_create(&baton, scratch_pool);
+  processor->dir_added = diff_dir_added;
+  processor->dir_changed = diff_dir_changed;
+  processor->dir_deleted = diff_dir_deleted;
+  processor->file_added = diff_file_added;
+  processor->file_changed = diff_file_changed;
+  processor->file_deleted = diff_file_deleted;
+
+  diff_processor = processor;
+  if (reverse_merge)
+    diff_processor = svn_diff__tree_processor_reverse_create(diff_processor,
+                                                             NULL,
+                                                             scratch_pool);
+
+  /* Filter the first path component using a filter processor, until we fixed
+     the diff processing to handle this directly */
+  diff_processor = svn_diff__tree_processor_filter_create(
+                     diff_processor, target1, scratch_pool);
 
   SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                                anchor2, NULL, NULL, FALSE,

Modified: subversion/branches/resolve-incoming-add/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/resolve-incoming-add/subversion/libsvn_wc/conflicts.c?rev=1762881&r1=1762880&r2=1762881&view=diff
==============================================================================
--- subversion/branches/resolve-incoming-add/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/resolve-incoming-add/subversion/libsvn_wc/conflicts.c Fri Sep 30 11:01:20 2016
@@ -3874,20 +3874,3 @@ svn_wc__guess_incoming_move_target_nodes
 
   return SVN_NO_ERROR;
 }
-
-svn_error_t *
-svn_wc__get_merge_incoming_add_diff_processor(
-  const svn_diff_tree_processor_t **diff_processor,
-  void **diff_processor_baton,
-  const char *target_abspath,
-  const char *prefix_relpath,
-  svn_boolean_t reverse_merge,
-  svn_wc_context_t *wc_ctx,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool)
-{
-  return svn_error_trace(svn_wc__db_get_merge_incoming_add_diff_processor(
-                           diff_processor, diff_processor_baton,
-                           target_abspath, prefix_relpath, reverse_merge,
-                           wc_ctx->db, result_pool, scratch_pool));
-}

Modified: subversion/branches/resolve-incoming-add/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/resolve-incoming-add/subversion/libsvn_wc/wc_db.h?rev=1762881&r1=1762880&r2=1762881&view=diff
==============================================================================
--- subversion/branches/resolve-incoming-add/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/resolve-incoming-add/subversion/libsvn_wc/wc_db.h Fri Sep 30 11:01:20 2016
@@ -3493,18 +3493,6 @@ svn_wc__find_repos_node_in_wc(apr_array_
                               svn_revnum_t rev,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool);
-
-svn_error_t *
-svn_wc__db_get_merge_incoming_add_diff_processor(
-  const svn_diff_tree_processor_t **diff_processor,
-  void **diff_processor_baton,
-  const char *target_abspath,
-  const char *prefix_relpath,
-  svn_boolean_t reverse_merge,
-  svn_wc__db_t *db,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool);
-
 /* @} */
 
 typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton,