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 2015/09/06 09:05:57 UTC

svn commit: r1701445 - in /subversion/branches/move-tracking-2/subversion: include/private/svn_branch.h include/private/svn_editor3e.h libsvn_delta/branch.c libsvn_delta/compat3e.c libsvn_delta/editor3e.c svnmover/svnmover.c

Author: julianfoad
Date: Sun Sep  6 07:05:57 2015
New Revision: 1701445

URL: http://svn.apache.org/r1701445
Log:
On the 'move-tracking-2' branch: Add an editor method 'open_branch'.

This gets rid of some direct access to the editor's txn.

* subversion/include/private/svn_branch.h,
  subversion/libsvn_delta/branch.c
  (svn_branch_id_split): Newly public; renamed from 'branch_id_split'.
  (svn_branch_state_parse): Track the rename.

* subversion/include/private/svn_editor3e.h
  (svn_editor3_open_branch,
   svn_editor3_cb_open_branch_t): New.
  (svn_editor3_cb_funcs_t): Add the new method.

* subversion/libsvn_delta/editor3e.c
  (svn_editor3_open_branch,
   wrap_open_branch,
   change_detection_open_branch): New.
  (svn_editor3__get_debug_editor,
   svn_editor3__change_detection_editor): Add the new method to the vtable.

* subversion/libsvn_delta/compat3e.c
  (editor3_open_branch): New.
  (svn_editor3_in_memory,
   svn_editor3__ev3_from_delta_for_commit): Add it to the vtable.
  (editor3_alter): Move the EID allocation hack to here...

* subversion/svnmover/svnmover.c
  (subtree_replay): ... from here. Take a branch id instead of a pointer.
  (svn_branch_replay): Use the new editor method. Use branch ids instead of
    pointers.
  (replay): Pass a branch id instead of a pointer.
  (mk_branch): Use the new editor method. Return a branch id instead of a
    pointer.
  (execute): Adjust the call to mk_branch.

Modified:
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h?rev=1701445&r1=1701444&r2=1701445&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h Sun Sep  6 07:05:57 2015
@@ -274,6 +274,14 @@ const char *
 svn_branch_get_id(svn_branch_state_t *branch,
                   apr_pool_t *result_pool);
 
+/*
+ */
+void
+svn_branch_id_split(const char **outer_bid,
+                    int *outer_eid,
+                    const char *bid,
+                    apr_pool_t *result_pool);
+
 /* Create a new branch at OUTER_BRANCH:OUTER_EID, with no elements
  * (not even a root element).
  *

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h?rev=1701445&r1=1701444&r2=1701445&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h Sun Sep  6 07:05:57 2015
@@ -582,6 +582,43 @@ svn_error_t *
 svn_editor3_new_eid(svn_editor3_t *editor,
                     svn_branch_eid_t *eid_p);
 
+/** Create a new branch or access an existing branch.
+ *
+ * When creating a branch, declare its root element id to be ROOT_EID. If
+ * ROOT_EID is -1, allocate a new EID for its root. Do not instantiate the
+ * root element, nor any other elements.
+ *
+ * We use a common 'open subbranch' method for both 'find' and 'add'
+ * cases, according to the principle that the editor dictates the new
+ * state without reference to the old state.
+ *
+ * This must be used before editing the resulting branch. In that sense
+ * this method conceptually returns a "branch editor" for the designated
+ * branch.
+ *
+ * ### Should we take a single branch-id parameter instead of taking
+ *     (outer-bid, outer-eid) and returning the new branch-id?
+ *
+ *     If we want to think of this as a "txn editor" method and we want
+ *     random access to any branch, that would be a good option.
+ *
+ *     If we want to think of this as a "branch editor" method then
+ *     outer-branch-id conceptually identifies "this branch" that we're
+ *     editing and could be represented instead by a different value of
+ *     the "editor" parameter; and the subbranch must be an immediate child.
+ *
+ * ### Only the 'add' case needs the subbranch root EID.
+ *     In the 'add' case will we want to take a 'branched from' param,
+ *     and can we have that in the combined method too?
+ */
+svn_error_t *
+svn_editor3_open_branch(svn_editor3_t *editor,
+                        const char **new_branch_id_p,
+                        const char *outer_branch_id,
+                        int outer_eid,
+                        int root_eid,
+                        apr_pool_t *result_pool);
+
 /** Specify the tree position and payload of the element of @a branch_id
  * identified by @a eid.
  *
@@ -817,6 +854,17 @@ typedef svn_error_t *(*svn_editor3_cb_ne
   svn_branch_eid_t *eid_p,
   apr_pool_t *scratch_pool);
 
+/** @see svn_editor3_open_branch(), #svn_editor3_t
+ */
+typedef svn_error_t *(*svn_editor3_cb_open_branch_t)(
+  void *baton,
+  const char **new_branch_id_p,
+  const char *outer_branch_id,
+  int outer_eid,
+  int root_eid,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool);
+
 /** @see svn_editor3_alter(), #svn_editor3_t
  */
 typedef svn_error_t *(*svn_editor3_cb_alter_t)(
@@ -901,6 +949,7 @@ typedef svn_error_t *(*svn_editor3_cb_ab
 typedef struct svn_editor3_cb_funcs_t
 {
   svn_editor3_cb_new_eid_t cb_new_eid;
+  svn_editor3_cb_open_branch_t cb_open_branch;
   svn_editor3_cb_alter_t cb_alter;
   svn_editor3_cb_copy_one_t cb_copy_one;
   svn_editor3_cb_copy_tree_t cb_copy_tree;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c?rev=1701445&r1=1701444&r2=1701445&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Sun Sep  6 07:05:57 2015
@@ -1017,11 +1017,11 @@ parse_element_line(int *eid_p,
  * For a top-level branch, set *OUTER_BID to NULL and *OUTER_EID to the
  * top-level branch number.
  */
-static void
-branch_id_split(const char **outer_bid,
-                int *outer_eid,
-                const char *bid,
-                apr_pool_t *result_pool)
+void
+svn_branch_id_split(const char **outer_bid,
+                    int *outer_eid,
+                    const char *bid,
+                    apr_pool_t *result_pool)
 {
   char *last_dot = strrchr(bid, '.');
 
@@ -1061,7 +1061,7 @@ svn_branch_state_parse(svn_branch_state_
   {
     const char *outer_bid;
 
-    branch_id_split(&outer_bid, &outer_eid, bid, scratch_pool);
+    svn_branch_id_split(&outer_bid, &outer_eid, bid, scratch_pool);
     if (outer_bid)
       {
         outer_branch

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c?rev=1701445&r1=1701444&r2=1701445&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c Sun Sep  6 07:05:57 2015
@@ -1151,6 +1151,39 @@ editor3_new_eid(void *baton,
 
 /* An #svn_editor3_t method. */
 static svn_error_t *
+editor3_open_branch(void *baton,
+                       const char **new_branch_id_p,
+                       const char *outer_branch_id,
+                       int outer_eid,
+                       int root_eid,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
+{
+  ev3_from_delta_baton_t *eb = baton;
+  svn_branch_state_t *outer_branch
+    = svn_branch_revision_root_get_branch_by_id(eb->edited_rev_root,
+                                                outer_branch_id, scratch_pool);
+  svn_branch_state_t *new_branch;
+
+  /* if the subbranch already exists, just return its bid */
+  *new_branch_id_p
+    = apr_psprintf(result_pool, "%s.%d", outer_branch_id, outer_eid);
+  new_branch
+    = svn_branch_revision_root_get_branch_by_id(eb->edited_rev_root,
+                                                *new_branch_id_p,
+                                                scratch_pool);
+  if (new_branch)
+    return SVN_NO_ERROR;
+
+  new_branch = svn_branch_add_new_branch(eb->edited_rev_root,
+                                         outer_branch, outer_eid,
+                                         root_eid, scratch_pool);
+  *new_branch_id_p = svn_branch_get_id(new_branch, result_pool);
+  return SVN_NO_ERROR;
+}
+
+/* An #svn_editor3_t method. */
+static svn_error_t *
 editor3_alter(void *baton,
               const char *branch_id,
               svn_branch_eid_t eid,
@@ -1164,6 +1197,13 @@ editor3_alter(void *baton,
     = svn_branch_revision_root_get_branch_by_id(eb->edited_rev_root,
                                                 branch_id, scratch_pool);
 
+  /* ### Ensure the requested EIDs are allocated... This is not the
+         right way to do it. Instead the Editor should map 'to be
+         created' EIDs to new EIDs? See BRANCH-README. */
+  while (eid >= eb->edited_rev_root->next_eid
+         || (new_parent_eid >= eb->edited_rev_root->next_eid))
+    svn_branch_revision_root_new_eid(eb->edited_rev_root);
+
   if (new_payload)
     {
       SVN_DBG(("alter(e%d): parent e%d, name '%s', kind %s",
@@ -1930,6 +1970,7 @@ svn_editor3_in_memory(svn_editor3_t **ed
 {
   static const svn_editor3_cb_funcs_t editor_funcs = {
     editor3_new_eid,
+    editor3_open_branch,
     editor3_alter,
     editor3_copy_one,
     editor3_copy_tree,
@@ -1972,6 +2013,7 @@ svn_editor3__ev3_from_delta_for_commit(
 {
   static const svn_editor3_cb_funcs_t editor_funcs = {
     editor3_new_eid,
+    editor3_open_branch,
     editor3_alter,
     editor3_copy_one,
     editor3_copy_tree,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c?rev=1701445&r1=1701444&r2=1701445&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c Sun Sep  6 07:05:57 2015
@@ -204,6 +204,24 @@ svn_editor3_new_eid(svn_editor3_t *edito
 }
 
 svn_error_t *
+svn_editor3_open_branch(svn_editor3_t *editor,
+                        const char **new_branch_id_p,
+                        const char *outer_branch_id,
+                        int outer_eid,
+                        int root_eid,
+                        apr_pool_t *result_pool)
+{
+  SVN_ERR_ASSERT(VALID_EID(outer_eid));
+  SVN_ERR_ASSERT(VALID_EID(root_eid));
+
+  DO_CALLBACK(editor, cb_open_branch,
+              5(new_branch_id_p, outer_branch_id, outer_eid, root_eid,
+                result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_editor3_alter(svn_editor3_t *editor,
                   const char *branch_id,
                   svn_branch_eid_t eid,
@@ -410,6 +428,26 @@ wrap_new_eid(void *baton,
 }
 
 static svn_error_t *
+wrap_open_branch(void *baton,
+                 const char **new_branch_id_p,
+                 const char *outer_branch_id,
+                 int outer_eid,
+                 int root_eid,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  wrapper_baton_t *eb = baton;
+
+  /*dbg(eb, scratch_pool, "%s : open_branch(...)",
+      eid_str(eid, scratch_pool), ...);*/
+  SVN_ERR(svn_editor3_open_branch(eb->wrapped_editor,
+                                     new_branch_id_p,
+                                     outer_branch_id, outer_eid, root_eid,
+                                     result_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 wrap_alter(void *baton,
            const char *branch_id,
            svn_branch_eid_t eid,
@@ -539,6 +577,7 @@ svn_editor3__get_debug_editor(svn_editor
 {
   static const svn_editor3_cb_funcs_t wrapper_funcs = {
     wrap_new_eid,
+    wrap_open_branch,
     wrap_alter,
     wrap_copy_one,
     wrap_copy_tree,
@@ -598,6 +637,24 @@ change_detection_new_eid(void *baton,
 }
 
 static svn_error_t *
+change_detection_open_branch(void *baton,
+                             const char **new_branch_id_p,
+                             const char *outer_branch_id,
+                             int outer_eid,
+                             int root_eid,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
+  change_detection_baton_t *eb = baton;
+
+  SVN_ERR(svn_editor3_open_branch(eb->wrapped_editor,
+                                  new_branch_id_p,
+                                  outer_branch_id, outer_eid, root_eid,
+                                  result_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 change_detection_alter(void *baton,
            const char *branch_id,
            svn_branch_eid_t eid,
@@ -716,6 +773,7 @@ svn_editor3__change_detection_editor(svn
 {
   static const svn_editor3_cb_funcs_t wrapper_funcs = {
     change_detection_new_eid,
+    change_detection_open_branch,
     change_detection_alter,
     change_detection_copy_one,
     change_detection_copy_tree,

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=1701445&r1=1701444&r2=1701445&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Sun Sep  6 07:05:57 2015
@@ -272,7 +272,7 @@ wc_create(svnmover_wc_t **wc_p,
  */
 static svn_error_t *
 subtree_replay(svn_editor3_t *editor,
-               svn_branch_state_t *edit_branch,
+               const char *edit_branch_id,
                svn_branch_subtree_t *s_left,
                svn_branch_subtree_t *s_right,
                apr_pool_t *scratch_pool)
@@ -303,16 +303,6 @@ subtree_replay(svn_editor3_t *editor,
                      || svn_element_payload_invariants(e1->payload));
       if (e0 || e1)
         {
-          const char *edit_branch_id
-            = svn_branch_get_id(edit_branch, scratch_pool);
-
-          /* ### Ensure the requested EIDs are allocated... This is not the
-                 right way to do it. Instead the Editor should map 'to be
-                 created' EIDs to new EIDs? See BRANCH-README. */
-          while (eid >= edit_branch->rev_root->next_eid
-                 || (e1 && e1->parent_eid >= edit_branch->rev_root->next_eid))
-            svn_branch_revision_root_new_eid(edit_branch->rev_root);
-
           if (e0 && e1)
             {
               SVN_DBG(("replay: alter e%d", eid));
@@ -349,7 +339,7 @@ subtree_replay(svn_editor3_t *editor,
  */
 static svn_error_t *
 svn_branch_replay(svn_editor3_t *editor,
-                  svn_branch_state_t *edit_branch,
+                  const char *edit_branch_id,
                   svn_branch_subtree_t *s_left,
                   svn_branch_subtree_t *s_right,
                   apr_pool_t *scratch_pool)
@@ -360,7 +350,7 @@ svn_branch_replay(svn_editor3_t *editor,
   if (s_right)
     {
       /* Replay this branch */
-      SVN_ERR(subtree_replay(editor, edit_branch, s_left, s_right,
+      SVN_ERR(subtree_replay(editor, edit_branch_id, s_left, s_right,
                              scratch_pool));
     }
   else
@@ -391,44 +381,22 @@ svn_branch_replay(svn_editor3_t *editor,
             = s_left ? svn_int_hash_get(s_left->subbranches, this_eid) : NULL;
           svn_branch_subtree_t *this_s_right
             = s_right ? svn_int_hash_get(s_right->subbranches, this_eid) : NULL;
-          svn_branch_state_t *edit_subbranch;
+          const char *edit_subbranch_id = NULL;
 
-          /* If the subbranch is to be edited or deleted, first look up the
-             corresponding edit branch; or, if the subbranch is to be added,
-             create a new edit branch. */
-          if (this_s_left)
-            {
-              edit_subbranch = svn_branch_get_subbranch_at_eid(
-                                 edit_branch, this_eid, scratch_pool);
-              /* There might not be such a subbranch, for example if we are
-                 replaying into a txn based on an older base revision. Then
-                 what?
-
-                 For now, we leave EDIT_BRANCH as NULL and so drop all the
-                 changes.
-
-                 ### It may be better to create an edit branch and then
-                 attempt to apply the changes into it.
-
-                 ### Ultimately, the editor API should not require us to
-                 'create' a branch here outside the editor. Instead we we
-                 should just pass the subbranch id through to the editor,
-                 along with the changes to the subbranch, and let the editor
-                 decide how to handle it.
-               */
-            }
-          else
+          /* If the subbranch is to be edited or added, first look up the
+             corresponding edit subbranch, or, if not found, create one. */
+          if (this_s_right)
             {
-              edit_subbranch = svn_branch_add_new_branch(
-                                 edit_branch->rev_root,
-                                 edit_branch, this_eid,
-                                 this_s_right->root_eid, scratch_pool);
+              SVN_ERR(svn_editor3_open_branch(editor, &edit_subbranch_id,
+                                              edit_branch_id, this_eid,
+                                              this_s_right->root_eid,
+                                              scratch_pool));
             }
 
           /* recurse */
-          if (edit_subbranch)
+          if (edit_subbranch_id)
             {
-              SVN_ERR(svn_branch_replay(editor, edit_subbranch,
+              SVN_ERR(svn_branch_replay(editor, edit_subbranch_id,
                                         this_s_left, this_s_right, scratch_pool));
             }
         }
@@ -454,11 +422,13 @@ replay(svn_editor3_t *editor,
   svn_branch_subtree_t *s_right
     = right_branch ? svn_branch_get_subtree(right_branch, right_branch->root_eid,
                                             scratch_pool) : NULL;
+  const char *edit_root_branch_id
+    = svn_branch_get_id(edit_root_branch, scratch_pool);
 
   SVN_ERR_ASSERT(editor && edit_root_branch);
   SVN_ERR_ASSERT(left_branch || right_branch);
 
-  SVN_ERR(svn_branch_replay(editor, edit_root_branch,
+  SVN_ERR(svn_branch_replay(editor, edit_root_branch_id,
                             s_left, s_right, scratch_pool));
   return SVN_NO_ERROR;
 }
@@ -2242,7 +2212,7 @@ svn_branch_log(svn_editor3_t *editor,
  * The subbranch will consist of a single element given by PAYLOAD.
  */
 static svn_error_t *
-mk_branch(svn_branch_state_t **new_branch_p,
+mk_branch(const char **new_branch_id_p,
           svn_editor3_t *editor,
           svn_branch_state_t *outer_branch,
           int outer_parent_eid,
@@ -2251,25 +2221,29 @@ mk_branch(svn_branch_state_t **new_branc
           apr_pool_t *scratch_pool)
 {
   const char *outer_branch_id = svn_branch_get_id(outer_branch, scratch_pool);
-  int new_outer_eid;
-  svn_branch_state_t *new_branch;
+  int new_outer_eid, new_inner_eid;
+  const char *new_branch_id;
 
   SVN_ERR(svn_editor3_new_eid(editor, &new_outer_eid));
   SVN_ERR(svn_editor3_alter(editor,
                             outer_branch_id, new_outer_eid,
                             outer_parent_eid, outer_name,
                             NULL /*new_payload*/));
-  new_branch = svn_branch_add_new_branch(
-                 outer_branch->rev_root,
-                 outer_branch, new_outer_eid, -1/*new_root_eid*/,
-                 scratch_pool);
-  svn_branch_update_element(new_branch, new_branch->root_eid,
-                            -1, "", payload);
-  notify_v("A    %s%s",
+
+  SVN_ERR(svn_editor3_new_eid(editor, &new_inner_eid));
+  SVN_ERR(svn_editor3_open_branch(editor, &new_branch_id,
+                                  outer_branch_id, new_outer_eid,
+                                  new_inner_eid, scratch_pool));
+  SVN_ERR(svn_editor3_alter(editor,
+                            new_branch_id, new_inner_eid,
+                            -1, "", payload));
+
+  notify_v("A    %s (branch %s)",
            svn_branch_get_path_by_eid(outer_branch, new_outer_eid,
                                       scratch_pool),
-           branch_str(new_branch, scratch_pool));
-  *new_branch_p = new_branch;
+           new_branch_id);
+  if (new_branch_id_p)
+    *new_branch_id_p = new_branch_id;
   return SVN_NO_ERROR;
 }
 
@@ -3135,9 +3109,8 @@ execute(svnmover_wc_t *wc,
             apr_hash_t *props = apr_hash_make(iterpool);
             svn_element_payload_t *payload
               = svn_element_payload_create_dir(props, iterpool);
-            svn_branch_state_t *new_branch;
 
-            SVN_ERR(mk_branch(&new_branch,
+            SVN_ERR(mk_branch(NULL,
                               editor, arg[0]->parent_el_rev->branch,
                               arg[0]->parent_el_rev->eid, arg[0]->path_name,
                               payload, iterpool));