subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1657686 - in /subversion/trunk/subversion/libsvn_wc: wc-queries.sql wc_db.c wc_db_private.h wc_db_update_move.c
Date Thu, 05 Feb 2015 20:46:54 GMT
Author: rhuijben
Date: Thu Feb  5 20:46:53 2015
New Revision: 1657686

URL: http://svn.apache.org/r1657686
Log:
Turn the replace_moved_layer() function in the move-update logic into an
internal wc_db function. This allows hiding a few more functions that are
too easy to abuse. And this function might be useful outside the move logic.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_DESCENDANTS_OP_DEPTH_RV): Handle incomplete presence.
  (STMT_SELECT_NO_LONGER_MOVED_RV): Obtain shadowing information.
  (STMT_DELETE_NO_LOWER_LAYER): Remove unused statement.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_extend_parent_delete): Make static and rename to...
  (db_extend_parent_delete): ... this.
  (svn_wc__db_retract_parent_delete): Make static and rename to...
  (db_retract_parent_delete): ... this.
  (insert_base_node,
   db_base_remove): Update caller.
  (svn_wc__db_op_copy_layer_internal): New function.

* subversion/libsvn_wc/wc_db_private.h
  (svn_wc__db_extend_parent_delete,
   svn_wc__db_retract_parent_delete): Remove functions.
  (svn_wc__db_op_copy_layer_internal): New function.

* subversion/libsvn_wc/wc_db_update_move.c
  (delete_move_leaf): Remove function. Folded queries to fold this
    function into its only caller.
  (replace_moved_layer): Moved to wc_db.c as svn_wc__db_op_copy_layer_internal.
  (drive_tree_conflict_editor): Update caller. Verify lock.
  (bump_moved_layer): Update caller. Verify lock on origin.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db_private.h
    subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Feb  5 20:46:53 2015
@@ -291,7 +291,7 @@ FROM nodes
 WHERE wc_id = ?1
   AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND op_depth = ?3
-  AND presence = MAP_NORMAL
+  AND presence in (MAP_NORMAL, MAP_INCOMPLETE)
 ORDER BY local_relpath DESC
 
 -- STMT_COPY_NODE_MOVE
@@ -314,11 +314,17 @@ FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
 
 -- STMT_SELECT_NO_LONGER_MOVED_RV
-SELECT d.local_relpath, RELPATH_SKIP_JOIN(?2, ?4, d.local_relpath) srp
+SELECT d.local_relpath, RELPATH_SKIP_JOIN(?2, ?4, d.local_relpath) srp,
+       b.presence, b.op_depth
 FROM nodes d
-WHERE wc_id = ?1
-  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
-  AND op_depth = ?3
+LEFT OUTER JOIN nodes b ON b.wc_id = ?1 AND b.local_relpath = d.local_relpath
+            AND b.op_depth = (SELECT MAX(x.op_depth) FROM nodes x
+                              WHERE x.wc_id = ?1
+                                AND x.local_relpath = b.local_relpath
+                                AND x.op_depth < ?3)
+WHERE d.wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(d.local_relpath, ?2)
+  AND d.op_depth = ?3
   AND NOT EXISTS(SELECT * FROM nodes s
                  WHERE s.wc_id = ?1
                    AND s.local_relpath = srp
@@ -968,17 +974,6 @@ INSERT INTO nodes (
     parent_relpath, presence, kind)
 VALUES(?1, ?2, ?3, ?4, MAP_BASE_DELETED, ?5)
 
--- STMT_DELETE_NO_LOWER_LAYER
-DELETE FROM nodes
- WHERE wc_id = ?1
-   AND local_relpath = ?2
-   AND op_depth = ?3
-   AND NOT EXISTS (SELECT 1 FROM nodes n
-                    WHERE n.wc_id = ?1
-                    AND n.local_relpath = nodes.local_relpath
-                    AND n.op_depth = ?4
-                    AND n.presence IN (MAP_NORMAL, MAP_INCOMPLETE))
-
 -- STMT_REPLACE_WITH_BASE_DELETED
 INSERT OR REPLACE INTO nodes (wc_id, local_relpath, op_depth, parent_relpath,
                               kind, moved_to, presence)

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb  5 20:46:53 2015
@@ -569,13 +569,54 @@ blank_ibb(insert_base_baton_t *pibb)
 }
 
 
-svn_error_t *
-svn_wc__db_extend_parent_delete(svn_boolean_t *added_delete,
-                                svn_wc__db_wcroot_t *wcroot,
-                                const char *local_relpath,
-                                svn_node_kind_t kind,
-                                int op_depth,
-                                apr_pool_t *scratch_pool)
+/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
+
+   ### What about KIND and OP_DEPTH?  KIND ought to be redundant; I'm
+       discussing on dev@ whether we can let that be null for presence
+       == base-deleted.  OP_DEPTH is the op-depth of what, and why?
+       It is used to select the lowest working node higher than OP_DEPTH,
+       so, in terms of the API, OP_DEPTH means ...?
+
+   Given a wc:
+
+              0         1         2         3         4
+              normal
+   A          normal
+   A/B        normal              normal
+   A/B/C                          not-pres  normal
+   A/B/C/D                                            normal
+
+   That is checkout, delete A/B, copy a replacement A/B, delete copied
+   child A/B/C, add replacement A/B/C, add A/B/C/D.
+
+   Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
+   must extend the A/B deletion:
+
+              0         1         2         3         4
+              normal
+   A          normal
+   A/B        normal              normal
+   A/B/C      normal              not-pres  normal
+   A/B/C/D    normal              base-del            normal
+   A/B/C/D/E  normal              base-del
+
+   When adding a node if the parent has a higher working node then the
+   parent node is deleted (or replaced) and the delete must be extended
+   to cover new node.
+
+   In the example above A/B/C/D and A/B/C/D/E are the nodes that get
+   the extended delete, A/B/C is already deleted.
+
+   If ADDED_DELETE is not NULL, set *ADDED_DELETE to TRUE if a new delete
+   was recorded, otherwise to FALSE.
+ */
+static svn_error_t *
+db_extend_parent_delete(svn_boolean_t *added_delete,
+                        svn_wc__db_wcroot_t *wcroot,
+                        const char *local_relpath,
+                        svn_node_kind_t kind,
+                        int op_depth,
+                        apr_pool_t *scratch_pool)
 {
   svn_boolean_t have_row;
   svn_sqlite__stmt_t *stmt;
@@ -623,7 +664,7 @@ svn_wc__db_extend_parent_delete(svn_bool
 }
 
 
-/* This is the reverse of svn_wc__db_extend_parent_delete.
+/* This is the reverse of db_extend_parent_delete.
 
    When removing a node if the parent has a higher working node then
    the parent node and this node are both deleted or replaced and any
@@ -633,11 +674,11 @@ svn_wc__db_extend_parent_delete(svn_bool
    only uses this function within an sqlite transaction if atomic
    behavior is needed.
  */
-svn_error_t *
-svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
-                                 const char *local_relpath,
-                                 int op_depth,
-                                 apr_pool_t *scratch_pool)
+static svn_error_t *
+db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
+                         const char *local_relpath,
+                         int op_depth,
+                         apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
@@ -840,17 +881,17 @@ insert_base_node(const insert_base_baton
               || (pibb->status == svn_wc__db_status_incomplete))
           && ! pibb->file_external)
         {
-          SVN_ERR(svn_wc__db_extend_parent_delete(NULL,
-                                                  wcroot, local_relpath,
-                                                  pibb->kind, 0,
-                                                  scratch_pool));
+          SVN_ERR(db_extend_parent_delete(NULL,
+                                          wcroot, local_relpath,
+                                          pibb->kind, 0,
+                                          scratch_pool));
         }
       else if (pibb->status == svn_wc__db_status_not_present
                || pibb->status == svn_wc__db_status_server_excluded
                || pibb->status == svn_wc__db_status_excluded)
         {
-          SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
-                                                   scratch_pool));
+          SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0,
+                                           scratch_pool));
         }
     }
 
@@ -2395,8 +2436,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
-  SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
-                                           scratch_pool));
+  SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0, scratch_pool));
 
   /* Step 6: Delete actual node if we don't keep working */
   if (! keep_working)
@@ -4804,6 +4844,185 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
+                                  const char *src_op_relpath,
+                                  int src_op_depth,
+                                  const char *dst_op_relpath,
+                                  svn_skel_t *conflict,
+                                  svn_skel_t *work_items,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt, *stmt2;
+  svn_boolean_t have_row;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int dst_op_depth = relpath_depth(dst_op_relpath);
+  svn_boolean_t locked;
+  svn_error_t *err = NULL;
+
+  SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot, dst_op_relpath,
+                                               FALSE, scratch_pool));
+
+  if (!locked)
+    return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
+                             _("No write-lock in '%s'"),
+                             path_for_error_message(wcroot, dst_op_relpath,
+                                                    scratch_pool));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+                                    STMT_COPY_NODE_MOVE));
+
+  /* Replace entire subtree at one op-depth. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_LAYER_FOR_REPLACE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
+                            src_op_relpath, src_op_depth,
+                            dst_op_relpath, dst_op_depth));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  while (have_row)
+    {
+      const char *src_relpath;
+      const char *dst_relpath;
+      svn_boolean_t exists;
+
+      svn_pool_clear(iterpool);
+
+      src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+      dst_relpath = svn_sqlite__column_text(stmt, 2, iterpool);
+
+      exists = !svn_sqlite__column_is_null(stmt, 3);
+
+      err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
+                              src_relpath, src_op_depth,
+                              dst_relpath, dst_op_depth,
+                              svn_relpath_dirname(dst_relpath, iterpool));
+      if (!err)
+        err = svn_sqlite__step_done(stmt2);
+
+      /* stmt2 is reset (never modified or by step_done) */
+
+      if (err)
+        break;
+
+      if (strlen(dst_relpath) > strlen(dst_op_relpath))
+        {
+          svn_boolean_t added_delete = FALSE;
+          svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
+
+          /* The op root can't be shadowed, so extension of a parent delete
+             is only needed when the parent can be deleted */
+          if (relpath_depth(dst_relpath) > (dst_op_depth+1))
+            {
+              err = db_extend_parent_delete(&added_delete, wcroot, dst_relpath,
+                                            kind, dst_op_depth, iterpool);
+
+              if (err)
+                break;
+            }
+
+          if (exists)
+            {
+              svn_wc__db_status_t presence;
+
+              presence = svn_sqlite__column_token(stmt, 3, presence_map);
+
+              if (presence == svn_wc__db_status_not_present)
+                exists = FALSE;
+            }
+
+          /* ### Fails in a few tests... Needs further research */
+          /*SVN_ERR_ASSERT(!(exists && added_delete));*/
+
+          if (!exists)
+            {
+              svn_boolean_t shadowed;
+
+              shadowed = svn_sqlite__column_int(stmt, 4);
+
+              /*if (!shadowed && !added_delete)
+                {
+                  err = svn_error_createf(
+                              SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+                              _("Node '%s' was unexpectedly added unshadowed"),
+                                path_for_error_message(wcroot, dst_relpath,
+                                                       iterpool));
+                  break;
+                }*/
+            }
+        }
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+
+  SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+  /* And now remove the records that are no longer needed */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_NO_LONGER_MOVED_RV));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
+                            dst_op_relpath, dst_op_depth,
+                            src_op_relpath, src_op_depth));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  while (have_row)
+    {
+      const char *dst_relpath;
+      svn_wc__db_status_t shadowed_presence;
+
+      svn_pool_clear(iterpool);
+
+      dst_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+
+      if (!svn_sqlite__column_is_null(stmt, 2))
+        shadowed_presence = svn_sqlite__column_token(stmt, 2, presence_map);
+      else
+        shadowed_presence = svn_wc__db_status_not_present;
+
+      if (shadowed_presence != svn_wc__db_status_normal
+          && shadowed_presence != svn_wc__db_status_incomplete)
+        {
+          err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+                                            STMT_DELETE_NODE);
+        }
+      else
+        {
+          err =svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+                                         STMT_REPLACE_WITH_BASE_DELETED);
+        }
+
+      if (!err)
+        err = svn_sqlite__bindf(stmt2, "isd", wcroot->wc_id, dst_relpath,
+                                             dst_op_depth);
+
+      if (!err)
+        err = svn_sqlite__step_done(stmt2);
+
+      /* stmt2 is reset (never modified or by step_done) */
+
+      if (err)
+        break;
+
+      /* Retract base-delete for the node itself */
+      err = db_retract_parent_delete(wcroot, dst_relpath, dst_op_depth,
+                                     scratch_pool);
+
+      if (err)
+        break;
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+  svn_pool_destroy(iterpool);
+
+  SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+  SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
+  if (conflict)
+    SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, dst_op_relpath /* ## */,
+                                              conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
 
 /* The txn body of svn_wc__db_op_handle_move_back */
 static svn_error_t *

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_private.h?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_private.h Thu Feb  5 20:46:53 2015
@@ -394,61 +394,18 @@ svn_wc__db_get_children_op_depth(apr_has
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool);
 
-
-/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
-
-   ### What about KIND and OP_DEPTH?  KIND ought to be redundant; I'm
-       discussing on dev@ whether we can let that be null for presence
-       == base-deleted.  OP_DEPTH is the op-depth of what, and why?
-       It is used to select the lowest working node higher than OP_DEPTH,
-       so, in terms of the API, OP_DEPTH means ...?
-
-   Given a wc:
-
-              0         1         2         3         4
-              normal
-   A          normal
-   A/B        normal              normal
-   A/B/C                          not-pres  normal
-   A/B/C/D                                            normal
-
-   That is checkout, delete A/B, copy a replacement A/B, delete copied
-   child A/B/C, add replacement A/B/C, add A/B/C/D.
-
-   Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
-   must extend the A/B deletion:
-
-              0         1         2         3         4
-              normal
-   A          normal
-   A/B        normal              normal
-   A/B/C      normal              not-pres  normal
-   A/B/C/D    normal              base-del            normal
-   A/B/C/D/E  normal              base-del
-
-   When adding a node if the parent has a higher working node then the
-   parent node is deleted (or replaced) and the delete must be extended
-   to cover new node.
-
-   In the example above A/B/C/D and A/B/C/D/E are the nodes that get
-   the extended delete, A/B/C is already deleted.
-
-   If ADDED_DELETE is not NULL, set *ADDED_DELETE to TRUE if a new delete
-   was recorded, otherwise to FALSE.
- */
+/* Update the single op-depth layer in the move destination subtree
+   rooted at DST_RELPATH to make it match the move source subtree
+   rooted at SRC_RELPATH. */
 svn_error_t *
-svn_wc__db_extend_parent_delete(svn_boolean_t *added_delete,
-                                svn_wc__db_wcroot_t *wcroot,
-                                const char *local_relpath,
-                                svn_node_kind_t kind,
-                                int op_depth,
-                                apr_pool_t *scratch_pool);
+svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
+                                  const char *src_op_relpath,
+                                  int src_op_depth,
+                                  const char *dst_op_relpath,
+                                  svn_skel_t *conflict,
+                                  svn_skel_t *work_items,
+                                  apr_pool_t *scratch_pool);
 
-svn_error_t *
-svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
-                                 const char *local_relpath,
-                                 int op_depth,
-                                 apr_pool_t *scratch_pool);
 
 /* Extract the moved-to information for LOCAL_RELPATH at OP-DEPTH by
    examining the lowest working node above OP_DEPTH.  The output paths

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Thu Feb  5 20:46:53 2015
@@ -1233,63 +1233,6 @@ tc_editor_delete(update_move_baton_t *b,
   return SVN_NO_ERROR;
 }
 
-/* Delete handling for a node and its shadowing */
-static svn_error_t *
-delete_move_leaf(svn_wc__db_wcroot_t *wcroot,
-                 const char *local_relpath,
-                 int op_depth,
-                 apr_pool_t *scratch_pool)
-{
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-  int op_depth_below;
-
-  /* Deleting the ROWS is valid as long as we update the parent before
-     committing the transaction.  The removed rows could have been
-     replacing a lower layer in which case we need to add base-deleted
-     rows. */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_SELECT_HIGHEST_WORKING_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
-                            svn_relpath_dirname(local_relpath, scratch_pool),
-                            op_depth));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  if (have_row)
-    op_depth_below = svn_sqlite__column_int(stmt, 0);
-  SVN_ERR(svn_sqlite__reset(stmt));
-  if (have_row)
-    {
-      /* Remove non-shadowing nodes. */
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_DELETE_NO_LOWER_LAYER));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, local_relpath,
-                                op_depth, op_depth_below));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-
-      /* Convert remaining shadowing nodes to presence='base-deleted'. */
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_REPLACE_WITH_BASE_DELETED));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
-                                op_depth));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-  else
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_DELETE_NODE));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
-                                op_depth));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-
-  /* Retract base-delete for the node itself */
-  SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, op_depth,
-                                           scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
 /*
  * Driver code.
  *
@@ -1633,142 +1576,6 @@ update_moved_away_node(update_move_baton
   return SVN_NO_ERROR;
 }
 
-/* Update the single op-depth layer in the move destination subtree
-   rooted at DST_RELPATH to make it match the move source subtree
-   rooted at SRC_RELPATH. */
-static svn_error_t *
-replace_moved_layer(svn_wc__db_wcroot_t *wcroot,
-                    const char *src_op_relpath,
-                    int src_op_depth,
-                    const char *dst_op_relpath,
-                    apr_pool_t *scratch_pool)
-{
-  svn_sqlite__stmt_t *stmt, *stmt2;
-  svn_boolean_t have_row;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  int dst_op_depth = relpath_depth(dst_op_relpath);
-  svn_error_t *err = NULL;
-
-  SVN_ERR(verify_write_lock(wcroot, src_op_relpath, scratch_pool));
-  SVN_ERR(verify_write_lock(wcroot, dst_op_relpath, scratch_pool));
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt2, wcroot->sdb,
-                                    STMT_COPY_NODE_MOVE));
-
-  /* Replace entire subtree at one op-depth. */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_SELECT_LAYER_FOR_REPLACE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
-                            src_op_relpath, src_op_depth,
-                            dst_op_relpath, dst_op_depth));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  while (have_row)
-    {
-      const char *src_relpath;
-      const char *dst_relpath;
-      svn_boolean_t exists;
-
-      svn_pool_clear(iterpool);
-
-      src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
-      dst_relpath = svn_sqlite__column_text(stmt, 2, iterpool);
-
-      exists = !svn_sqlite__column_is_null(stmt, 3);
-
-      err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
-                              src_relpath, src_op_depth,
-                              dst_relpath, dst_op_depth,
-                              svn_relpath_dirname(dst_relpath, iterpool));
-      if (!err)
-        err = svn_sqlite__step_done(stmt2);
-
-      /* stmt2 is reset (never modified or by step_done) */
-
-      if (err)
-        break;
-
-      if (strlen(dst_relpath) > strlen(dst_op_relpath))
-        {
-          svn_boolean_t added_delete = FALSE;
-          svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
-
-          /* The op root can't be shadowed, so extension of a parent delete
-             is only needed when the parent can be deleted */
-          if (relpath_depth(dst_relpath) > (dst_op_depth+1))
-            {
-              err = svn_wc__db_extend_parent_delete(&added_delete,
-                                                    wcroot, dst_relpath, kind,
-                                                    dst_op_depth, iterpool);
-
-              if (err)
-                break;
-            }
-
-          if (exists)
-            {
-              svn_wc__db_status_t presence;
-
-              presence = svn_sqlite__column_token(stmt, 3, presence_map);
-
-              if (presence == svn_wc__db_status_not_present)
-                exists = FALSE;
-            }
-
-          /* ### Fails in a few tests... Needs further research */
-          /*SVN_ERR_ASSERT(!(exists && added_delete));*/
-
-          if (!exists)
-            {
-              svn_boolean_t shadowed;
-
-              shadowed = svn_sqlite__column_int(stmt, 4);
-
-              /*if (!shadowed && !added_delete)
-                {
-                  err = svn_error_createf(
-                              SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                              _("Node '%s' was unexpectedly added unshadowed"),
-                                path_for_error_message(wcroot, dst_relpath,
-                                                       iterpool));
-                  break;
-                }*/
-            }
-        }
-
-      SVN_ERR(svn_sqlite__step(&have_row, stmt));
-    }
-
-  SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-
-  /* And now remove the records that are no longer needed */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_SELECT_NO_LONGER_MOVED_RV));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
-                            dst_op_relpath, dst_op_depth,
-                            src_op_relpath, src_op_depth));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  while (have_row)
-    {
-      const char *dst_relpath;
-
-      svn_pool_clear(iterpool);
-
-      dst_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
-
-      err = delete_move_leaf(wcroot, dst_relpath, dst_op_depth,
-                             iterpool);
-
-      if (err)
-        break;
-
-      SVN_ERR(svn_sqlite__step(&have_row, stmt));
-    }
-  svn_pool_destroy(iterpool);
-
-  SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-  return SVN_NO_ERROR;
-}
-
 /* Transfer changes from the move source to the move destination.
  *
  * Drive the editor with the difference between DST_RELPATH
@@ -1796,6 +1603,8 @@ drive_tree_conflict_editor(update_move_b
                            void *cancel_baton,
                            apr_pool_t *scratch_pool)
 {
+  SVN_ERR(verify_write_lock(wcroot, src_relpath, scratch_pool));
+  SVN_ERR(verify_write_lock(wcroot, dst_relpath, scratch_pool));
   /*
    * Refuse to auto-resolve unsupported tree conflicts.
    */
@@ -1815,8 +1624,9 @@ drive_tree_conflict_editor(update_move_b
                                  dst_relpath, FALSE /* never shadowed */,
                                  db, scratch_pool));
 
-  SVN_ERR(replace_moved_layer(wcroot, src_relpath, src_op_depth, dst_relpath,
-                              scratch_pool));
+  SVN_ERR(svn_wc__db_op_copy_layer_internal(wcroot, src_relpath, src_op_depth,
+                                            dst_relpath, NULL, NULL,
+                                            scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2318,10 +2128,13 @@ bump_moved_layer(svn_boolean_t *recurse,
   if (!conflict)
     {
       /* ### TODO: verify moved_here? */
-      SVN_ERR(replace_moved_layer(wcroot,
-                                  src_relpath, op_depth,
-                                  dst_relpath,
-                                  scratch_pool));
+
+      SVN_ERR(verify_write_lock(wcroot, src_relpath, scratch_pool));
+
+      SVN_ERR(svn_wc__db_op_copy_layer_internal(wcroot,
+                                                src_relpath, op_depth,
+                                                dst_relpath, NULL, NULL,
+                                                scratch_pool));
 
       *recurse = TRUE;
     }



Mime
View raw message