Author: stsp
Date: Wed Jul 13 16:33:12 2011
New Revision: 1146119

URL: http://svn.apache.org/viewvc?rev=1146119&view=rev
Log:
Start recording the difference between a copy and a move in wc.db.

With this commit we set the existing 'moved_here' boolean flag in
the NODES table on the node which is the add-half of a copy (as well
as any children of this node) if a copy was in fact a move.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_WORKING_NODE_COPY_FROM_BASE,
   STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING,
   STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH): Fill the 'moved_here' column
    from a new query parameter.

* subversion/libsvn_wc/copy.c
  (copy_versioned_file, copy_versioned_dir): New parameter IS_MOVE which
   indicates whether the copy is in fact a move. Call the appropriate
   svn_wc__db_op interface function depending on this parameter.
  (copy_or_move): New, contains most code from svn_wc_copy3(). Pass IS_MOVE
   parameter down to copy_versioned_file() and copy_versioned_dir().
  (svn_wc_copy3): Reimplement as a thin wrapper around copy_or_move().
  (svn_wc_move): Call copy_or_move() instead of svn_wc_copy3().

* subversion/libsvn_wc/entries.c
  (read_one_entry): Treat status 'moved-here' the same as status 'copied'
   so that moved nodes appear as normal copies to old code.

* subversion/libsvn_wc/wc_db.c
  (db_op_copy): Add new parameter IS_MOVE, which is passed into DB queries
   as appropriate.
  (op_copy_baton): New field IS_MOVE.
  (op_copy_txn): Pass IS_MOVE from copy baton to db_op_copy().
  (svn_wc__db_op_copy): Initialise new field IS_MOVE in copy baton.
  (db_op_copy_shadowed_layer): Pass 0 for 'moved_here' query parameter
   while creating in-DB copies of nodes shadowed by a copy/move operation.
  (svn_wc__db_op_move): Implement. Set IS_MOVE in the copy baton so that
   the copy code will treat this operation as a move.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_op_copy_shadowed_layer): Tweak docstring.
  (svn_wc__db_op_move): Make signature match that of svn_wc__op_copy()
   and tweak the docstring.

Modified:
    subversion/trunk/subversion/libsvn_wc/copy.c
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Wed Jul 13 16:33:12 2011
@@ -175,6 +175,9 @@ copy_pristine_text_if_necessary(svn_wc__
    otherwise copy both the versioned metadata and the filesystem node (even
    if it is the wrong kind, and recursively if it is a dir).
 
+   If IS_MOVE is true, record move information in working copy meta
+   data in addition to copying the file.
+
    If the versioned file has a text conflict, and the .mine file exists in
    the filesystem, copy the .mine file to DST_ABSPATH.  Otherwise, copy the
    versioned file itself.
@@ -190,6 +193,7 @@ copy_versioned_file(svn_wc__db_t *db,
                     const svn_checksum_t *checksum,
                     svn_boolean_t metadata_only,
                     svn_boolean_t conflicted,
+                    svn_boolean_t is_move,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     svn_wc_notify_func2_t notify_func,
@@ -308,8 +312,14 @@ copy_versioned_file(svn_wc__db_t *db,
 
   /* Copy the (single) node's metadata, and move the new filesystem node
      into place. */
-  SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath, dst_op_root_abspath,
-                             work_items, scratch_pool));
+  if (is_move)
+    SVN_ERR(svn_wc__db_op_move(db, src_abspath, dst_abspath,
+                               dst_op_root_abspath, work_items,
+                               scratch_pool));
+  else
+    SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
+                               dst_op_root_abspath, work_items,
+                               scratch_pool));
   SVN_ERR(svn_wc__wq_run(db, dir_abspath,
                          cancel_func, cancel_baton, scratch_pool));
 
@@ -327,7 +337,9 @@ copy_versioned_file(svn_wc__db_t *db,
 /* Copy the versioned dir SRC_ABSPATH in DB to the path DST_ABSPATH in DB,
    recursively.  If METADATA_ONLY is true, copy only the versioned metadata,
    otherwise copy both the versioned metadata and the filesystem nodes (even
-   if they are the wrong kind, and including unversioned children). */
+   if they are the wrong kind, and including unversioned children).
+   If IS_MOVE is true, record move information in working copy meta
+   data in addition to copying the directory. */
 static svn_error_t *
 copy_versioned_dir(svn_wc__db_t *db,
                    const char *src_abspath,
@@ -335,6 +347,7 @@ copy_versioned_dir(svn_wc__db_t *db,
                    const char *dst_op_root_abspath,
                    const char *tmpdir_abspath,
                    svn_boolean_t metadata_only,
+                   svn_boolean_t is_move,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    svn_wc_notify_func2_t notify_func,
@@ -370,8 +383,14 @@ copy_versioned_dir(svn_wc__db_t *db,
 
   /* Copy the (single) node's metadata, and move the new filesystem node
      into place. */
-  SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath, dst_op_root_abspath,
-                             work_items, scratch_pool));
+  if (is_move)
+    SVN_ERR(svn_wc__db_op_move(db, src_abspath, dst_abspath,
+                               dst_op_root_abspath, work_items,
+                               scratch_pool));
+  else
+    SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
+                               dst_op_root_abspath, work_items,
+                               scratch_pool));
   SVN_ERR(svn_wc__wq_run(db, dir_abspath,
                          cancel_func, cancel_baton, scratch_pool));
 
@@ -456,6 +475,7 @@ copy_versioned_dir(svn_wc__db_t *db,
                                             dst_op_root_abspath,
                                             tmpdir_abspath, checksum,
                                             metadata_only, conflicted,
+                                            is_move,
                                             cancel_func, cancel_baton,
                                             NULL, NULL,
                                             iterpool));
@@ -464,7 +484,7 @@ copy_versioned_dir(svn_wc__db_t *db,
             SVN_ERR(copy_versioned_dir(db,
                                        child_src_abspath, child_dst_abspath,
                                        dst_op_root_abspath, tmpdir_abspath,
-                                       metadata_only,
+                                       metadata_only, is_move,
                                        cancel_func, cancel_baton, NULL, NULL,
                                        iterpool));
           else
@@ -479,9 +499,14 @@ copy_versioned_dir(svn_wc__db_t *db,
         {
           /* This will be copied as some kind of deletion. Don't touch
              any actual files */
-          SVN_ERR(svn_wc__db_op_copy(db, child_src_abspath, child_dst_abspath,
-                                     dst_op_root_abspath,
-                                     NULL, iterpool));
+          if (is_move)
+            SVN_ERR(svn_wc__db_op_move(db, child_src_abspath,
+                                       child_dst_abspath, dst_op_root_abspath,
+                                       NULL, scratch_pool));
+          else
+            SVN_ERR(svn_wc__db_op_copy(db, child_src_abspath,
+                                       child_dst_abspath, dst_op_root_abspath,
+                                       NULL, iterpool));
 
           /* Don't recurse on children while all we do is creating not-present
              children */
@@ -563,13 +588,15 @@ copy_versioned_dir(svn_wc__db_t *db,
 }
 
 
-/* Public Interface */
-
-svn_error_t *
-svn_wc_copy3(svn_wc_context_t *wc_ctx,
+/* The guts of svn_wc_copy3() and svn_wc_move().
+ * The additional parameter IS_MOVE indicates whether this is a copy or
+ * a move operation. */
+static svn_error_t *
+copy_or_move(svn_wc_context_t *wc_ctx,
              const char *src_abspath,
              const char *dst_abspath,
              svn_boolean_t metadata_only,
+             svn_boolean_t is_move,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
              svn_wc_notify_func2_t notify_func,
@@ -744,7 +771,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
     {
       SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
                                   tmpdir_abspath, checksum,
-                                  metadata_only, conflicted,
+                                  metadata_only, conflicted, is_move,
                                   cancel_func, cancel_baton,
                                   notify_func, notify_baton,
                                   scratch_pool));
@@ -753,7 +780,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
     {
       SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
                                  tmpdir_abspath,
-                                 metadata_only,
+                                 metadata_only, is_move,
                                  cancel_func, cancel_baton,
                                  notify_func, notify_baton,
                                  scratch_pool));
@@ -762,6 +789,28 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
   return SVN_NO_ERROR;
 }
 
+
+/* Public Interface */
+
+svn_error_t *
+svn_wc_copy3(svn_wc_context_t *wc_ctx,
+             const char *src_abspath,
+             const char *dst_abspath,
+             svn_boolean_t metadata_only,
+             svn_cancel_func_t cancel_func,
+             void *cancel_baton,
+             svn_wc_notify_func2_t notify_func,
+             void *notify_baton,
+             apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(copy_or_move(wc_ctx, src_abspath, dst_abspath,
+                                      metadata_only, FALSE /* is_move */,
+                                      cancel_func, cancel_baton,
+                                      notify_func, notify_baton,
+                                      scratch_pool));
+}
+
+
 /* Remove the conflict markers of NODE_ABSPATH, that were left over after
    copying NODE_ABSPATH from SRC_ABSPATH.
 
@@ -922,8 +971,9 @@ svn_wc_move(svn_wc_context_t *wc_ctx,
             apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db = wc_ctx->db;
-  SVN_ERR(svn_wc_copy3(wc_ctx, src_abspath, dst_abspath,
+  SVN_ERR(copy_or_move(wc_ctx, src_abspath, dst_abspath,
                        TRUE /* metadata_only */,
+                       TRUE /* is_move */,
                        cancel_func, cancel_baton,
                        notify_func, notify_baton,
                        scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Jul 13 16:33:12 2011
@@ -637,7 +637,10 @@ read_one_entry(const svn_wc_entry_t **ne
           /* ### scan_addition may need to be updated to avoid returning
              ### status_copied in this case.  */
         }
-      else if (work_status == svn_wc__db_status_copied)
+      /* For backwards-compatiblity purposes we treat moves just like
+       * regular copies. */
+      else if (work_status == svn_wc__db_status_copied ||
+               work_status == svn_wc__db_status_moved_here)
         {
           entry->copied = TRUE;
 
@@ -662,7 +665,8 @@ read_one_entry(const svn_wc_entry_t **ne
           svn_boolean_t is_copied_child;
           svn_boolean_t is_mixed_rev = FALSE;
 
-          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied);
+          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied ||
+                         work_status == svn_wc__db_status_moved_here);
 
           /* If this node inherits copyfrom information from an
              ancestor node, then it must be a copied child.  */

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Jul 13 16:33:12 
2011
@@ -870,11 +870,11 @@ WHERE wc_id = ?1
 -- STMT_INSERT_WORKING_NODE_COPY_FROM_BASE
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id,
-    repos_path, revision, presence, depth, kind, changed_revision,
+    repos_path, revision, presence, depth, moved_here, kind, changed_revision,
     changed_date, changed_author, checksum, properties, translated_size,
     last_mod_time, symlink_target )
 SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
-    repos_id, repos_path, revision, ?6 /*presence*/, depth,
+    repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7/*moved_here*/,
     kind, changed_revision, changed_date, changed_author, checksum, properties,
     translated_size, last_mod_time, symlink_target
 FROM nodes
@@ -883,11 +883,11 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 -- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
-    revision, presence, depth, kind, changed_revision, changed_date,
+    revision, presence, depth, moved_here, kind, changed_revision, 
changed_date,
     changed_author, checksum, properties, translated_size, last_mod_time,
     symlink_target )
 SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
-    repos_id, repos_path, revision, ?6 /*presence*/, depth,
+    repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7 /*moved_here*/,
     kind, changed_revision, changed_date, changed_author, checksum, properties,
     translated_size, last_mod_time, symlink_target
 FROM nodes
@@ -898,15 +898,15 @@ LIMIT 1
 -- STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
-    revision, presence, depth, kind, changed_revision, changed_date,
+    revision, presence, depth, moved_here, kind, changed_revision, 
changed_date,
     changed_author, checksum, properties, translated_size, last_mod_time,
     symlink_target )
 SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
-    repos_id, repos_path, revision, ?6 /*presence*/,
-    depth, kind, changed_revision, changed_date, changed_author, checksum,
+    repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7 /*moved_here*/,
+    kind, changed_revision, changed_date, changed_author, checksum,
     properties, translated_size, last_mod_time, symlink_target
 FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?7
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?8
 
 -- STMT_INSERT_ACTUAL_NODE_FROM_ACTUAL_NODE
 INSERT OR REPLACE INTO actual_node (

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Jul 13 16:33:12 2011
@@ -3422,14 +3422,15 @@ op_depth_for_copy(apr_int64_t *op_depth,
                   apr_pool_t *scratch_pool);
 
 
-/* Like svn_wc__db_op_copy(), but with WCROOT+LOCAL_RELPATH instead of
-   DB+LOCAL_ABSPATH.  */
+/* Like svn_wc__db_op_copy()/svn_wc__db_op_move(), but with
+   WCROOT+LOCAL_RELPATH instead of DB+LOCAL_ABSPATH.  */
 static svn_error_t *
 db_op_copy(svn_wc__db_wcroot_t *src_wcroot,
            const char *src_relpath,
            svn_wc__db_wcroot_t *dst_wcroot,
            const char *dst_relpath,
            const svn_skel_t *work_items,
+           svn_boolean_t is_move,
            apr_pool_t *scratch_pool)
 {
   const char *copyfrom_relpath;
@@ -3544,12 +3545,13 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
         SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
                           STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "issist",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issisti",
                     src_wcroot->wc_id, src_relpath,
                     dst_relpath,
                     dst_op_depth,
                     dst_parent_relpath,
-                    presence_map, dst_presence));
+                    presence_map, dst_presence,
+                    (apr_int64_t)(is_move ? 1 : 0)));
 
       SVN_ERR(svn_sqlite__step_done(stmt));
 
@@ -3619,6 +3621,7 @@ struct op_copy_baton
   const char *dst_relpath;
 
   const svn_skel_t *work_items;
+  svn_boolean_t is_move;
 };
 
 /* Helper for svn_wc__db_op_copy.
@@ -3642,7 +3645,7 @@ op_copy_txn(void * baton, svn_sqlite__db
 
   SVN_ERR(db_op_copy(ocb->src_wcroot, ocb->src_relpath,
                      ocb->dst_wcroot, ocb->dst_relpath,
-                     ocb->work_items, scratch_pool));
+                     ocb->work_items, ocb->is_move, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3673,6 +3676,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
   VERIFY_USABLE_WCROOT(ocb.dst_wcroot);
 
   ocb.work_items = work_items;
+  ocb.is_move = FALSE;
 
   /* Call with the sdb in src_wcroot. It might call itself again to
      also obtain a lock in dst_wcroot */
@@ -3812,15 +3816,16 @@ db_op_copy_shadowed_layer(svn_wc__db_wcr
         SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
                              STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "issist",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issisti",
                         src_wcroot->wc_id, src_relpath,
                         dst_relpath,
                         dst_op_depth,
                         svn_relpath_dirname(dst_relpath, iterpool),
-                        presence_map, dst_presence));
+                        presence_map, dst_presence,
+                        (apr_int64_t)0));
 
       if (src_op_depth > 0)
-        SVN_ERR(svn_sqlite__bind_int64(stmt, 7, src_op_depth));
+        SVN_ERR(svn_sqlite__bind_int64(stmt, 8, src_op_depth));
 
       SVN_ERR(svn_sqlite__step_done(stmt));
 
@@ -4713,12 +4718,36 @@ svn_error_t *
 svn_wc__db_op_move(svn_wc__db_t *db,
                    const char *src_abspath,
                    const char *dst_abspath,
+                   const char *dst_op_root_abspath,
+                   const svn_skel_t *work_items,
                    apr_pool_t *scratch_pool)
 {
+  struct op_copy_baton ocb = {0};
+
   SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
 
-  NOT_IMPLEMENTED();
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&ocb.src_wcroot,
+                                                &ocb.src_relpath, db,
+                                                src_abspath,
+                                                scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(ocb.src_wcroot);
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&ocb.dst_wcroot,
+                                                &ocb.dst_relpath,
+                                                db, dst_abspath,
+                                                scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(ocb.dst_wcroot);
+
+  ocb.work_items = work_items;
+  ocb.is_move = TRUE;
+
+  /* Call with the sdb in src_wcroot. It might call itself again to
+     also obtain a lock in dst_wcroot */
+  SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb, op_copy_txn, &ocb,
+                                scratch_pool));
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Jul 13 16:33:12 2011
@@ -1227,7 +1227,8 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
  * properly deleted.
  *
  * Usually this operation is directly followed by a call to svn_wc__db_op_copy
- * which performs the real copy from src_abspath to dst_abspath.
+ * or svn_wc__db_op_move which performs the real copy from src_abspath to
+ * dst_abspath.
  */
 svn_error_t *
 svn_wc__db_op_copy_shadowed_layer(svn_wc__db_t *db,
@@ -1427,12 +1428,20 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
                      apr_pool_t *scratch_pool);
 
 
-/* ### KFF: Would like to know behavior when dst_path already exists
-   ### and is a) a dir or b) a non-dir. */
+/* Move the node at SRC_ABSPATH (in NODES and ACTUAL_NODE tables) to
+ * DST_ABSPATH, both in DB but not necessarily in the same WC.  The parent
+ * of DST_ABSPATH must be a versioned directory.
+ *
+ * This move is NOT recursive. It simply establishes this one node, plus
+ * incomplete nodes for the children.
+ *
+ * Add WORK_ITEMS to the work queue. */
 svn_error_t *
 svn_wc__db_op_move(svn_wc__db_t *db,
                    const char *src_abspath,
                    const char *dst_abspath,
+                   const char *dst_op_root_abspath,
+                   const svn_skel_t *work_items,
                    apr_pool_t *scratch_pool);
 
 


Reply via email to