Author: rhuijben
Date: Tue Jun  7 10:43:07 2011
New Revision: 1132948

URL: http://svn.apache.org/viewvc?rev=1132948&view=rev
Log:
Reimplement most logic of r1132834 in svn_wc_move(). This removes the conflict
marker files (if they exist) after moving a node.

This patch doesn't fix the issue #3899 testcase as this resolves the copy to
working instead of the expected mine.
(I'm not sure which behavior we really want. I think <=1.6 used working by
 ignoring the marker files)

* subversion/libsvn_wc/copy.c
  (remove_node_conflict_markers): New function.
  (remove_all_conflict_markers): New function.
  (svn_wc_move): Remove conflict markers after renaming the directory.

* subversion/tests/cmdline/copy_tests.py
  (copy_and_move_conflicts): Handle test failure on Windows
    (similar to r1132731).

Modified:
    subversion/trunk/subversion/libsvn_wc/copy.c
    subversion/trunk/subversion/tests/cmdline/copy_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1132948&r1=1132947&r2=1132948&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Tue Jun  7 10:43:07 2011
@@ -778,6 +778,154 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
   return SVN_NO_ERROR;
 }
 
+/* Remove the conflict markers of NODE_ABSPATH, that were left over after
+   copying NODE_ABSPATH from SRC_ABSPATH. 
+
+   Only use this function when you know what you're doing. This function
+   explicitly ignores some case insensitivity issues!
+
+   */
+static svn_error_t *
+remove_node_conflict_markers(svn_wc__db_t *db,
+                             const char *src_abspath,
+                             const char *node_abspath,
+                             apr_pool_t *scratch_pool)
+{
+  const apr_array_header_t *conflicts;
+
+  SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, src_abspath,
+                                    scratch_pool, scratch_pool));
+
+  /* Do we have conflict markers that should be removed? */
+  if (conflicts != NULL)
+    {
+      int i;
+      const char *src_dir = svn_dirent_dirname(src_abspath, scratch_pool);
+      const char *dst_dir = svn_dirent_dirname(node_abspath, scratch_pool);
+
+      /* No iterpool: Maximum number of possible conflict markers is 4 */
+
+      for (i = 0; i < conflicts->nelts; i++)
+        {
+          const svn_wc_conflict_description2_t *desc;
+          const char *child_relpath;
+          const char *child_abpath;
+
+          desc = APR_ARRAY_IDX(conflicts, i,
+                               const svn_wc_conflict_description2_t*);
+
+          if (desc->kind != svn_wc_conflict_kind_text
+              && desc->kind != svn_wc_conflict_kind_property)
+            continue;
+
+          if (desc->base_abspath != NULL)
+            {
+              child_relpath = svn_dirent_is_child(src_dir, desc->base_abspath,
+                                                  NULL);
+
+              if (child_relpath)
+                {
+                  child_abpath = svn_dirent_join(dst_dir, child_relpath,
+                                                 scratch_pool);
+
+                  SVN_ERR(svn_io_remove_file2(child_abpath, TRUE,
+                                              scratch_pool));
+                }
+            }
+          if (desc->their_abspath != NULL)
+            {
+              child_relpath = svn_dirent_is_child(src_dir, desc->their_abspath,
+                                                  NULL);
+
+              if (child_relpath)
+                {
+                  child_abpath = svn_dirent_join(dst_dir, child_relpath,
+                                                 scratch_pool);
+
+                  SVN_ERR(svn_io_remove_file2(child_abpath, TRUE,
+                                              scratch_pool));
+                }
+            }
+          if (desc->my_abspath != NULL)
+            {
+              child_relpath = svn_dirent_is_child(src_dir, desc->my_abspath,
+                                                  NULL);
+
+              if (child_relpath)
+                {
+                  child_abpath = svn_dirent_join(dst_dir, child_relpath,
+                                                 scratch_pool);
+
+                  /* ### Copy child_abspath to node_abspath if it exists? */
+                  SVN_ERR(svn_io_remove_file2(child_abpath, TRUE,
+                                              scratch_pool));
+                }
+            }
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Remove all the conflict markers below SRC_DIR_ABSPATH, that were left over
+   after copying WC_DIR_ABSPATH from SRC_DIR_ABSPATH.
+
+   This function doesn't remove the conflict markers on WC_DIR_ABSPATH
+   itself!
+
+   Only use this function when you know what you're doing. This function
+   explicitly ignores some case insensitivity issues!
+   */
+static svn_error_t *
+remove_all_conflict_markers(svn_wc__db_t *db,
+                            const char *src_dir_abspath,
+                            const char *wc_dir_abspath,
+                            apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_hash_t *nodes;
+  apr_hash_t *conflicts; /* Unused */
+  apr_hash_index_t *hi;
+
+  /* Reuse a status helper to obtain all subdirs and conflicts in a single
+     db transaction. */
+  /* ### This uses a rifle to kill a fly. But at least it doesn't use heavy
+          artillery. */
+  SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts, db,
+                                        src_dir_abspath,
+                                        scratch_pool, iterpool));
+
+  for (hi = apr_hash_first(scratch_pool, nodes);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      const char *name = svn__apr_hash_index_key(hi);
+      struct svn_wc__db_info_t *info = svn__apr_hash_index_val(hi);
+
+      if (info->conflicted)
+        {
+          svn_pool_clear(iterpool);
+          SVN_ERR(remove_node_conflict_markers(
+                            db,
+                            svn_dirent_join(src_dir_abspath, name, iterpool),
+                            svn_dirent_join(wc_dir_abspath, name, iterpool),
+                            iterpool));
+        }
+      if (info->kind == svn_wc__db_kind_dir)
+        {
+          svn_pool_clear(iterpool);
+          SVN_ERR(remove_all_conflict_markers(
+                            db,
+                            svn_dirent_join(src_dir_abspath, name, iterpool),
+                            svn_dirent_join(wc_dir_abspath, name, iterpool),
+                            iterpool));
+        }
+    }
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc_move(svn_wc_context_t *wc_ctx,
             const char *src_abspath,
@@ -789,6 +937,7 @@ svn_wc_move(svn_wc_context_t *wc_ctx,
             void *notify_baton,
             apr_pool_t *scratch_pool)
 {
+  svn_wc__db_t *db = wc_ctx->db;
   SVN_ERR(svn_wc_copy3(wc_ctx, src_abspath, dst_abspath,
                        TRUE /* metadata_only */,
                        cancel_func, cancel_baton,
@@ -802,8 +951,26 @@ svn_wc_move(svn_wc_context_t *wc_ctx,
   if (!metadata_only)
     SVN_ERR(svn_io_file_rename(src_abspath, dst_abspath, scratch_pool));
 
-  /* ### TODO: Remove conflict marker left overs from dst_abspath (issue #3899)
-   */
+  {
+    svn_wc__db_kind_t kind;
+    svn_boolean_t conflicted;
+
+    SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL,
+                                 &conflicted, NULL, NULL, NULL,
+                                 NULL, NULL, NULL,
+                                 db, src_abspath,
+                                 scratch_pool, scratch_pool));
+
+    if (kind == svn_wc__db_kind_dir)
+      SVN_ERR(remove_all_conflict_markers(db, src_abspath, dst_abspath,
+                                          scratch_pool));
+
+    if (conflicted)
+      SVN_ERR(remove_node_conflict_markers(db, src_abspath, dst_abspath,
+                                           scratch_pool));
+  }
 
   SVN_ERR(svn_wc_delete4(wc_ctx, src_abspath, TRUE, FALSE,
                          cancel_func, cancel_baton,

Modified: subversion/trunk/subversion/tests/cmdline/copy_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/copy_tests.py?rev=1132948&r1=1132947&r2=1132948&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/copy_tests.py Tue Jun  7 10:43:07 
2011
@@ -5307,8 +5307,9 @@ def copy_and_move_conflicts(sbox):
 
   # Resolve one text conflict via marker file deletion.
   os.remove(wc('A/B/E/beta.merge-left.r3'))
-  os.rename(wc('A/B/E/beta.merge-right.r4'), wc('A/B/E/beta'))
   os.remove(wc('A/B/E/beta.working'))
+  os.remove(wc('A/B/E/beta'))
+  os.rename(wc('A/B/E/beta.merge-right.r4'), wc('A/B/E/beta'))
 
   # Prepare for local copies and moves.
   sbox.simple_mkdir('copy-dest')


Reply via email to