You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2016/12/20 14:56:57 UTC

svn commit: r1775296 - in /subversion/trunk/subversion: libsvn_client/mtcc.c tests/libsvn_client/mtcc-test.c

Author: rhuijben
Date: Tue Dec 20 14:56:57 2016
New Revision: 1775296

URL: http://svn.apache.org/viewvc?rev=1775296&view=rev
Log:
Resolve issue #4666 "svnmucc fails to delete directories that contain
just deletes", by handling this special corner case.

* subversion/libsvn_client/mtcc.c
  (mtcc_op_contains_non_delete): New function.
  (svn_client__mtcc_add_delete): Rename to...
  (mtcc_add_delete): ... and allow deleting directories that contain
    just deletes.
  (svn_client__mtcc_add_delete): New function around mtcc_add_delete.
  (svn_client__mtcc_add_move): Keep old behavior to avoid regression in
    case we move something that contains deletes. (Unsupported scenario
    in current implementation).

* subversion/tests/libsvn_client/mtcc-test.c
  (test_funcs): Remove XFail from test_move_and_delete_ancestor.

Modified:
    subversion/trunk/subversion/libsvn_client/mtcc.c
    subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c

Modified: subversion/trunk/subversion/libsvn_client/mtcc.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/mtcc.c?rev=1775296&r1=1775295&r2=1775296&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/mtcc.c (original)
+++ subversion/trunk/subversion/libsvn_client/mtcc.c Tue Dec 20 14:56:57 2016
@@ -568,10 +568,44 @@ svn_client__mtcc_add_copy(const char *sr
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_client__mtcc_add_delete(const char *relpath,
-                            svn_client__mtcc_t *mtcc,
-                            apr_pool_t *scratch_pool)
+/* Check if this operation contains at least one change that is not a
+   plain delete */
+static svn_boolean_t
+mtcc_op_contains_non_delete(const mtcc_op_t *op)
+{
+  if (op->kind != OP_OPEN_DIR && op->kind != OP_OPEN_FILE
+      && op->kind != OP_DELETE)
+    {
+      return TRUE;
+    }
+
+  if (op->prop_mods && op->prop_mods->nelts)
+    return TRUE;
+
+  if (op->src_stream)
+    return TRUE;
+
+  if (op->children)
+    {
+      int i;
+
+      for (i = 0; i < op->children->nelts; i++)
+        {
+          const mtcc_op_t *c_op = APR_ARRAY_IDX(op->children, i,
+                                                const mtcc_op_t *);
+
+          if (mtcc_op_contains_non_delete(c_op))
+            return TRUE;
+        }
+    }
+  return FALSE;
+}
+
+static svn_error_t *
+mtcc_add_delete(const char *relpath,
+                svn_boolean_t for_move,
+                svn_client__mtcc_t *mtcc,                
+                apr_pool_t *scratch_pool)
 {
   mtcc_op_t *op;
   svn_boolean_t created;
@@ -598,6 +632,20 @@ svn_client__mtcc_add_delete(const char *
       SVN_ERR(mtcc_op_find(&op, &created, relpath, mtcc->root_op, FALSE, TRUE,
                            TRUE, mtcc->pool, scratch_pool));
 
+      if (!for_move && !op && !created)
+        {
+          /* Allow deleting directories, that are unmodified except for
+              one or more deleted descendants */
+          
+          SVN_ERR(mtcc_op_find(&op, &created, relpath, mtcc->root_op, TRUE,
+                  FALSE, FALSE, mtcc->pool, scratch_pool));
+
+          if (op && mtcc_op_contains_non_delete(op))
+            op = NULL;
+          else
+            created = TRUE;
+        }
+
       if (!op || !created)
         {
           return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -614,6 +662,14 @@ svn_client__mtcc_add_delete(const char *
 }
 
 svn_error_t *
+svn_client__mtcc_add_delete(const char *relpath,
+                            svn_client__mtcc_t *mtcc,
+                            apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(mtcc_add_delete(relpath, FALSE, mtcc, scratch_pool));
+}
+
+svn_error_t *
 svn_client__mtcc_add_mkdir(const char *relpath,
                            svn_client__mtcc_t *mtcc,
                            apr_pool_t *scratch_pool)
@@ -662,7 +718,7 @@ svn_client__mtcc_add_move(const char *sr
 
   SVN_ERR(svn_client__mtcc_add_copy(src_relpath, mtcc->base_revision,
                                     dst_relpath, mtcc, scratch_pool));
-  SVN_ERR(svn_client__mtcc_add_delete(src_relpath, mtcc, scratch_pool));
+  SVN_ERR(mtcc_add_delete(src_relpath, TRUE, mtcc, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c?rev=1775296&r1=1775295&r2=1775296&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/mtcc-test.c Tue Dec 20 14:56:57 2016
@@ -840,7 +840,7 @@ static struct svn_test_descriptor_t test
                        "test ra_get_file_revs2 both ways"),
     SVN_TEST_OPTS_PASS(test_iprops_path_format,
                        "test iprops url format"),
-    SVN_TEST_OPTS_XFAIL(test_move_and_delete_ancestor,
+    SVN_TEST_OPTS_PASS(test_move_and_delete_ancestor,
                        "test move and delete ancestor (issue 4666)"),
     SVN_TEST_NULL
   };