Author: stsp
Date: Wed Aug 23 12:13:38 2017
New Revision: 1805889

URL: http://svn.apache.org/viewvc?rev=1805889&view=rev
Log:
On the addremove branch, support ambiguous file moves.

This makes 'svn addremove' represent ambiguous file moves as a deletion
with multiple copies of the deleted file.

* subversion/libsvn_client/addremove.c
  (suggest_moves): Return an array of possible move targets, rather than
   a single move target.
  (match_up_local_deletes_and_adds): If more than one move target was found,
   do not flag a move but make items appear as copies of the deleted item.

* subversion/tests/cmdline/addremove_tests.py
  (addremove_ambiguous_move_file, test_list): New test.

Modified:
    subversion/branches/addremove/subversion/libsvn_client/addremove.c
    subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py

Modified: subversion/branches/addremove/subversion/libsvn_client/addremove.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_client/addremove.c?rev=1805889&r1=1805888&r2=1805889&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_client/addremove.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_client/addremove.c Wed Aug 
23 12:13:38 2017
@@ -136,16 +136,23 @@ suggest_moves(apr_hash_t **moves,
 
       for (i = 0; i < similar_abspaths->nelts; i++)
         {
+          apr_array_header_t *move_targets;
           const char *similar_abspath = APR_ARRAY_IDX(similar_abspaths, i,
                                                       const char *);
 
           if (svn_hash_gets(deleted, similar_abspath) == NULL)
             continue; /* ### TODO treat as a copy? */
 
-          /* ### TODO deal with ambiguous moves */
-          svn_hash_sets(*moves,
-                        similar_abspath,
-                        apr_pstrdup(result_pool, added_abspath));
+          move_targets = svn_hash_gets(*moves, similar_abspath);
+          if (move_targets == NULL)
+            {
+              move_targets = apr_array_make(result_pool, 1,
+                                            sizeof (const char *));
+              svn_hash_sets(*moves, similar_abspath, move_targets);
+            }
+
+          APR_ARRAY_PUSH(move_targets, const char *) = 
+            apr_pstrdup(result_pool, added_abspath);
         }
     }
 
@@ -284,15 +291,22 @@ match_up_local_deletes_and_adds(const ch
        hi = apr_hash_next(hi))
     {
       const char *src_abspath = apr_hash_this_key(hi);
-      const char *dst_abspath = apr_hash_this_val(hi);
+      apr_array_header_t *move_targets = apr_hash_this_val(hi);
+      svn_boolean_t is_ambiguous_move = (move_targets->nelts > 1);
+      int i;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_wc__fixup_copyfrom(ctx->wc_ctx, src_abspath, dst_abspath,
-                                     TRUE, /* is_move */
-                                     ctx->cancel_func, ctx->cancel_baton,
-                                     ctx->notify_func2, ctx->notify_baton2,
-                                     iterpool));
+      for (i = 0; i < move_targets->nelts; i++) 
+        {
+          const char *dst_abspath = APR_ARRAY_IDX(move_targets, i,
+                                                  const char *);
+          SVN_ERR(svn_wc__fixup_copyfrom(ctx->wc_ctx, src_abspath, dst_abspath,
+                                         !is_ambiguous_move, /* is_move */
+                                         ctx->cancel_func, ctx->cancel_baton,
+                                         ctx->notify_func2, ctx->notify_baton2,
+                                         iterpool));
+        }
     }
   svn_pool_destroy(iterpool);
 

Modified: 
subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py?rev=1805889&r1=1805888&r2=1805889&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py 
(original)
+++ subversion/branches/addremove/subversion/tests/cmdline/addremove_tests.py 
Wed Aug 23 12:13:38 2017
@@ -118,6 +118,33 @@ def addremove_unversioned_move_file(sbox
   })
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+def addremove_ambiguous_move_file(sbox):
+  "addremove handles ambiguous file moves"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  oldfile_path = sbox.ospath('A/mu')
+  newfile_path = sbox.ospath('A/mu-moved')
+  newfile2_path = sbox.ospath('A/mu-moved2')
+  o = open(oldfile_path, 'r')
+  n = open(newfile_path, 'w')
+  n.write(o.read())
+  o.close()
+  n.close()
+  os.rename(oldfile_path, newfile2_path)
+
+  svntest.actions.run_and_verify_svn(None, [], 'addremove', wc_dir)
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='D ')
+  expected_status.add({
+    'A/mu-moved' : Item(status='A ', wc_rev='-', copied='+'),
+    'A/mu-moved2' : Item(status='A ', wc_rev='-', copied='+'),
+  })
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+
 ########################################################################
 # Run the tests
 
@@ -126,6 +153,7 @@ test_list = [ None,
               basic_addremove,
               addremove_ignore,
               addremove_unversioned_move_file,
+              addremove_ambiguous_move_file,
 ]
 
 if __name__ == '__main__':


Reply via email to