You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/01/08 14:23:24 UTC

svn commit: r1430272 - /subversion/trunk/subversion/libsvn_wc/copy.c

Author: stsp
Date: Tue Jan  8 13:23:23 2013
New Revision: 1430272

URL: http://svn.apache.org/viewvc?rev=1430272&view=rev
Log:
Degrade cross-wc moves to a copy+delete. We cannot currently track cross-wc
moves, and trying to do so leaves a broken move in the source WC.

Found by: danielsh

See for related discussion:
http://svn.haxx.se/dev/archive-2013-01/0147.shtml

* subversion/libsvn_wc/copy.c
  (copy_or_move): Add a new optional output parameter move_degraded_to_copy
   to let the caller know whether a move had to be degraded. Set this parameter
   for cross-WC moves.
  (svn_wc_copy3): Pass NULL for move_degraded_to_copy.
  (svn_wc__move2): If we find that a move has been degraded to a copy, perform
   a regular deletion of the move source.

Modified:
    subversion/trunk/subversion/libsvn_wc/copy.c

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1430272&r1=1430271&r2=1430272&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Tue Jan  8 13:23:23 2013
@@ -539,9 +539,13 @@ copy_versioned_dir(svn_wc__db_t *db,
 
 /* 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. */
+ * a move operation.
+ *
+ * If MOVE_DEGRADED_TO_COPY is not NULL and a move had to be degraded
+ * to a copy, then set *MOVE_DEGRADED_TO_COPY. */
 static svn_error_t *
-copy_or_move(svn_wc_context_t *wc_ctx,
+copy_or_move(svn_boolean_t *move_degraded_to_copy,
+             svn_wc_context_t *wc_ctx,
              const char *src_abspath,
              const char *dst_abspath,
              svn_boolean_t metadata_only,
@@ -759,6 +763,15 @@ copy_or_move(svn_wc_context_t *wc_ctx,
 
   within_one_wc = (strcmp(src_wcroot_abspath, dst_wcroot_abspath) == 0);
 
+  if (move_degraded_to_copy != NULL)
+    {
+      /* Cross-WC moves cannot be tracked.
+       * Degrade such moves to a copy+delete. */
+      *move_degraded_to_copy = (is_move && !within_one_wc);
+      if (*move_degraded_to_copy)
+        is_move = FALSE;
+    }
+
   if (src_db_kind == svn_kind_file
       || src_db_kind == svn_kind_symlink)
     {
@@ -812,7 +825,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
                               svn_dirent_dirname(dst_abspath, scratch_pool),
                               scratch_pool));
 
-  return svn_error_trace(copy_or_move(wc_ctx, src_abspath, dst_abspath,
+  return svn_error_trace(copy_or_move(NULL, wc_ctx, src_abspath, dst_abspath,
                                       metadata_only, FALSE /* is_move */,
                                       TRUE /* allow_mixed_revisions */,
                                       cancel_func, cancel_baton,
@@ -947,6 +960,7 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
               apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db = wc_ctx->db;
+  svn_boolean_t move_degraded_to_copy = FALSE;
 
   /* Verify that we have the required write locks. */
   SVN_ERR(svn_wc__write_check(wc_ctx->db,
@@ -956,7 +970,8 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
                               svn_dirent_dirname(dst_abspath, scratch_pool),
                               scratch_pool));
 
-  SVN_ERR(copy_or_move(wc_ctx, src_abspath, dst_abspath,
+  SVN_ERR(copy_or_move(&move_degraded_to_copy,
+                       wc_ctx, src_abspath, dst_abspath,
                        TRUE /* metadata_only */,
                        TRUE /* is_move */,
                        allow_mixed_revisions,
@@ -1003,7 +1018,7 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
   }
 
   SVN_ERR(svn_wc__delete_internal(wc_ctx, src_abspath, TRUE, FALSE,
-                                  dst_abspath,
+                                  move_degraded_to_copy ? NULL : dst_abspath,
                                   cancel_func, cancel_baton,
                                   notify_func, notify_baton,
                                   scratch_pool));