Author: julianfoad
Date: Thu Feb 26 17:42:15 2015
New Revision: 1662505

URL: http://svn.apache.org/r1662505
Log:
On the 'move-tracking-2' branch: When deleting and when merging a delete,
also delete nested branches.

* subversion/include/private/svn_editor3.h
  (svn_editor3_delete): Mention that the element to delete shall not be the
    branch root.
  (svn_branch_add_new_branch_instance): Tweak doc string.
  (svn_branch_delete_branch_instance_r,
   svn_branch_get_subbranches): New functions.

* subversion/libsvn_delta/branching.c
  (svn_branch_get_subbranches): Rename from branch_get_subbranches. Make
    public.
  (svn_branch_revision_root_delete_branch_instance,
   svn_branch_delete_branch_instance_r): New functions.
  (svn_branch_get_all_sub_branches,
   svn_branch_branch_subtree_r2): Track the rename.

* subversion/libsvn_delta/compat3b.c
  (editor3_delete): Also delete nested branches.

* subversion/libsvn_delta/editor3.c
  (svn_editor3_delete): Assert that we are not asked to delete the branch
    root element.

* subversion/svnmover/svnmover.c
  (execute): Error on trying to delete the repository root element. When
    deleting a subbranch root element, pass its location within the outer
    branch instead.

Modified:
    subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c

Modified: 
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h?rev=1662505&r1=1662504&r2=1662505&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h 
(original)
+++ 
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h 
Thu Feb 26 17:42:15 2015
@@ -1067,7 +1067,7 @@ svn_editor3_copy_tree(svn_editor3_t *edi
                       svn_editor3_eid_t new_parent_eid,
                       const char *new_name);
 
-/** Delete the existing element identified by @a eid.
+/** Delete the existing element of @a branch identified by @a eid.
  *
  * The delete is not explicitly recursive. However, unless otherwise
  * specified, the caller may assume that each element that has element
@@ -1075,7 +1075,7 @@ svn_editor3_copy_tree(svn_editor3_t *edi
  * recursively.
  *
  * If the element @a eid is a subbranch root, then delete that subbranch
- * (recursively).
+ * (recursively). The element @a eid is not the root element of @a branch.
  *
  * @a since_rev specifies the base revision on which this deletion was
  * performed: the server can consider the change "out of date" if a commit
@@ -1751,6 +1751,9 @@ svn_branch_instance_create(svn_branch_si
 
 /* Create a new branch instance at OUTER_BRANCH:OUTER_EID, of the branch class
  * BRANCH_SIBLING, with no elements (not even a root element).
+ *
+ * Do not require that a subbranch root element exists in OUTER_BRANCH,
+ * nor create one.
  */
 svn_branch_instance_t *
 svn_branch_add_new_branch_instance(svn_branch_instance_t *outer_branch,
@@ -1758,6 +1761,24 @@ svn_branch_add_new_branch_instance(svn_b
                                    svn_branch_sibling_t *branch_sibling,
                                    apr_pool_t *scratch_pool);
 
+/* Delete the branch instance BRANCH, and any subbranches recursively.
+ *
+ * Do not require that a subbranch root element exists in its outer branch,
+ * nor delete it if it does exist.
+ */
+void
+svn_branch_delete_branch_instance_r(svn_branch_instance_t *branch,
+                                    apr_pool_t *scratch_pool);
+
+/* Return an array of pointers to the branch instances that are immediate
+ * sub-branches of BRANCH at or below EID.
+ */
+apr_array_header_t *
+svn_branch_get_subbranches(const svn_branch_instance_t *branch,
+                           int eid,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
+
 /* Return an array of pointers to the branch instances that are immediate
  * sub-branches of BRANCH.
  */

Modified: 
subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c?rev=1662505&r1=1662504&r2=1662505&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c Thu 
Feb 26 17:42:15 2015
@@ -761,14 +761,11 @@ family_is_child(svn_branch_family_t *par
   return FALSE;
 }
 
-/* Return an array of pointers to the branch instances that are immediate
- * sub-branches of BRANCH at or below EID.
- */
-static apr_array_header_t *
-branch_get_sub_branches(const svn_branch_instance_t *branch,
-                        int eid,
-                        apr_pool_t *result_pool,
-                        apr_pool_t *scratch_pool)
+apr_array_header_t *
+svn_branch_get_subbranches(const svn_branch_instance_t *branch,
+                           int eid,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
 {
   svn_branch_family_t *family = branch->sibling_defn->family;
   const char *top_rrpath = svn_branch_get_rrpath_by_eid(branch, eid,
@@ -800,7 +797,7 @@ svn_branch_get_all_sub_branches(const sv
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
 {
-  return branch_get_sub_branches(branch, branch->sibling_defn->root_eid,
+  return svn_branch_get_subbranches(branch, branch->sibling_defn->root_eid,
                                  result_pool, scratch_pool);
 }
 
@@ -846,6 +843,52 @@ svn_branch_add_new_branch_instance(svn_b
   return branch_instance;
 }
 
+/* Remove branch-instance BRANCH from the list of branches in REV_ROOT.
+ */
+static void
+svn_branch_revision_root_delete_branch_instance(
+                                svn_branch_revision_root_t *rev_root,
+                                svn_branch_instance_t *branch,
+                                apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *rev_branches = rev_root->branch_instances;
+  int i;
+
+  SVN_ERR_ASSERT_NO_RETURN(branch->rev_root == rev_root);
+
+  for (i = 0; i < rev_branches->nelts; i++)
+    {
+      svn_branch_instance_t *b = APR_ARRAY_IDX(rev_branches, i, void *);
+
+      if (b == branch)
+        {
+          SVN_DBG(("deleting branch-instance b%d e%d", b->sibling_defn->bid, 
b->sibling_defn->root_eid));
+          svn_sort__array_delete(rev_branches, i, 1);
+          break;
+        }
+    }
+}
+
+void
+svn_branch_delete_branch_instance_r(svn_branch_instance_t *branch,
+                                    apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *subbranches;
+  int i;
+
+  subbranches = svn_branch_get_all_sub_branches(branch,
+                                                scratch_pool, scratch_pool);
+  for (i = 0; i < subbranches->nelts; i++)
+    {
+      svn_branch_instance_t *subbranch = APR_ARRAY_IDX(subbranches, i, void *);
+
+      svn_branch_delete_branch_instance_r(subbranch, scratch_pool);
+    }
+
+  
svn_branch_revision_root_delete_branch_instance(branch->outer_branch->rev_root,
+                                                  branch, scratch_pool);
+}
+
 
 /*
  * ========================================================================
@@ -1378,7 +1421,7 @@ svn_branch_branch_subtree_r2(svn_branch_
     apr_array_header_t *subbranches;
     int i;
 
-    subbranches = branch_get_sub_branches(from_branch, from_eid,
+    subbranches = svn_branch_get_subbranches(from_branch, from_eid,
                                           scratch_pool, scratch_pool);
     for (i = 0; i < subbranches->nelts; i++)
       {

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c?rev=1662505&r1=1662504&r2=1662505&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c Thu 
Feb 26 17:42:15 2015
@@ -1041,12 +1041,26 @@ editor3_delete(void *baton,
                    svn_editor3_eid_t eid,
                    apr_pool_t *scratch_pool)
 {
-  SVN_DBG(("delete(e%d)",
-           /*branch->sibling_defn->bid,*/ eid));
+  apr_array_header_t *subbranches;
+  int i;
 
-  svn_branch_map_delete(branch, eid /* ### , since_rev? */);
+  SVN_DBG(("delete(b%d e%d)",
+           branch->sibling_defn->bid, eid));
+
+  /* Delete nested branches. ### Shouldn't GC/purge-orphans take care of it? */
+  subbranches = svn_branch_get_subbranches(branch, eid,
+                                           scratch_pool, scratch_pool);
+  for (i = 0; i < subbranches->nelts; i++)
+    {
+      svn_branch_instance_t *b = APR_ARRAY_IDX(subbranches, i, void *);
 
-  /* ### TODO: Delete nested branches. */
+      SVN_DBG(("delete subbranch-tree (b%d) found at outer e%d",
+               b->sibling_defn->bid, b->outer_eid));
+      svn_branch_delete_branch_instance_r(b, scratch_pool);
+    }
+
+  /* Delete the specified element */
+  svn_branch_map_delete(branch, eid /* ### , since_rev? */);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c?rev=1662505&r1=1662504&r2=1662505&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c Thu 
Feb 26 17:42:15 2015
@@ -382,6 +382,7 @@ svn_editor3_delete(svn_editor3_t *editor
                    svn_editor3_eid_t eid)
 {
   SVN_ERR_ASSERT(VALID_EID(eid));
+  SVN_ERR_ASSERT(eid != branch->sibling_defn->root_eid);
   /* TODO: verify this element exists (in initial state) */
 
   DO_CALLBACK(editor, cb_delete,

Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1662505&r1=1662504&r2=1662505&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Thu Feb 
26 17:42:15 2015
@@ -1382,6 +1382,9 @@ commit_callback(const svn_commit_info_t
                              _("%s: Path '%s' not found"),              \
                              op, svn_relpath_dirname(action->relpath[i], 
pool));
 
+#define is_branch_root_element(branch, eid) \
+  ((branch)->sibling_defn->root_eid == (eid))
+
 static svn_error_t *
 execute(const apr_array_header_t *actions,
         const char *anchor_url,
@@ -1596,8 +1599,26 @@ execute(const apr_array_header_t *action
         case ACTION_RM:
           VERIFY_REV_UNSPECIFIED("rm", 0);
           VERIFY_EID_EXISTS("rm", 0);
-          SVN_ERR(svn_editor3_delete(editor, el_rev[0]->rev,
-                                     el_rev[0]->branch, el_rev[0]->eid));
+          {
+            svn_branch_instance_t *branch = el_rev[0]->branch;
+            int eid = el_rev[0]->eid;
+
+            /* If given a branch root element, look instead at the
+               subbranch-root element within the outer branch. */
+            if (is_branch_root_element(branch, eid))
+              {
+                if (! branch->outer_branch)
+                  return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+                                     _("rm: cannot remove the repository 
root"));
+
+                eid = el_rev[0]->branch->outer_eid;
+                branch = el_rev[0]->branch->outer_branch;
+              }
+
+            SVN_ERR(svn_editor3_delete(editor, el_rev[0]->rev,
+                                       branch, eid));
+          }
+          notify("D    %s", action->relpath[0]);
           made_changes = TRUE;
           break;
         case ACTION_MKDIR:


Reply via email to