You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sv...@apache.org on 2015/03/19 19:23:49 UTC

svn commit: r1667834 - in /subversion/branches/1.9.x: ./ STATUS subversion/libsvn_client/merge.c subversion/tests/cmdline/merge_tree_conflict_tests.py

Author: svn-role
Date: Thu Mar 19 18:23:48 2015
New Revision: 1667834

URL: http://svn.apache.org/r1667834
Log:
Merge r1666690 from trunk:

 * r1666690
   Record skipped tree during merge on the skip root instead of leaves
   Justification:
     Resolves a user reported problem in merge handling. Avoids unnecessary
     mergeinfo recording on multiple leaves when a single ancestor is shadowed.
   Votes:
     +1: rhuijben, brane, philip

Modified:
    subversion/branches/1.9.x/   (props changed)
    subversion/branches/1.9.x/STATUS
    subversion/branches/1.9.x/subversion/libsvn_client/merge.c
    subversion/branches/1.9.x/subversion/tests/cmdline/merge_tree_conflict_tests.py

Propchange: subversion/branches/1.9.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Mar 19 18:23:48 2015
@@ -89,4 +89,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1660545-1660547,1660549-1662901,1663003,1663338,1663347,1663374,1663450,1663697,1663706,1663749,1664078,1664080,1664084-1664085,1664187,1664191,1664200,1664344,1664476,1664480-1664481,1664483,1664507,1664520-1664521,1664523,1664526-1664527,1664531-1664532,1664588,1664927,1665164,1665611-1665612,1665845,1665850,1665852,1665886,1666270,1666272,1666851
+/subversion/trunk:1660545-1660547,1660549-1662901,1663003,1663338,1663347,1663374,1663450,1663697,1663706,1663749,1664078,1664080,1664084-1664085,1664187,1664191,1664200,1664344,1664476,1664480-1664481,1664483,1664507,1664520-1664521,1664523,1664526-1664527,1664531-1664532,1664588,1664927,1665164,1665611-1665612,1665845,1665850,1665852,1665886,1666270,1666272,1666690,1666851

Modified: subversion/branches/1.9.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/STATUS?rev=1667834&r1=1667833&r2=1667834&view=diff
==============================================================================
--- subversion/branches/1.9.x/STATUS (original)
+++ subversion/branches/1.9.x/STATUS Thu Mar 19 18:23:48 2015
@@ -178,14 +178,6 @@ Veto-blocked changes:
 Approved changes:
 =================
 
- * r1666690
-   Record skipped tree during merge on the skip root instead of leaves
-   Justification:
-     Resolves a user reported problem in merge handling. Avoids unnecessary
-     mergeinfo recording on multiple leaves when a single ancestor is shadowed.
-   Votes:
-     +1: rhuijben, brane, philip
-
  * r1663183, r1663184
    Introduce build support for Visual Studio "2015"
    Justification:

Modified: subversion/branches/1.9.x/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/libsvn_client/merge.c?rev=1667834&r1=1667833&r2=1667834&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/1.9.x/subversion/libsvn_client/merge.c Thu Mar 19 18:23:48 2015
@@ -1267,13 +1267,14 @@ record_skip(merge_cmd_baton_t *merge_b,
             svn_node_kind_t kind,
             svn_wc_notify_action_t action,
             svn_wc_notify_state_t state,
+            struct merge_dir_baton_t *pdb,
             apr_pool_t *scratch_pool)
 {
   if (merge_b->record_only)
     return SVN_NO_ERROR; /* ### Why? - Legacy compatibility */
 
-  if (merge_b->merge_source.ancestral
-      || merge_b->reintegrate_merge)
+  if ((merge_b->merge_source.ancestral || merge_b->reintegrate_merge)
+      && !(pdb && pdb->shadowed))
     {
       store_path(merge_b->skipped_abspaths, local_abspath);
     }
@@ -2020,7 +2021,8 @@ merge_file_changed(const char *relpath,
           /* We haven't notified for this node yet: report a skip */
           SVN_ERR(record_skip(merge_b, local_abspath, svn_node_file,
                               svn_wc_notify_update_shadowed_update,
-                              fb->skip_reason, scratch_pool));
+                              fb->skip_reason, fb->parent_baton,
+                              scratch_pool));
         }
 
       return SVN_NO_ERROR;
@@ -2190,7 +2192,8 @@ merge_file_added(const char *relpath,
           /* We haven't notified for this node yet: report a skip */
           SVN_ERR(record_skip(merge_b, local_abspath, svn_node_file,
                               svn_wc_notify_update_shadowed_add,
-                              fb->skip_reason, scratch_pool));
+                              fb->skip_reason, fb->parent_baton,
+                              scratch_pool));
         }
 
       return SVN_NO_ERROR;
@@ -2401,7 +2404,8 @@ merge_file_deleted(const char *relpath,
           /* We haven't notified for this node yet: report a skip */
           SVN_ERR(record_skip(merge_b, local_abspath, svn_node_file,
                               svn_wc_notify_update_shadowed_delete,
-                              fb->skip_reason, scratch_pool));
+                              fb->skip_reason, fb->parent_baton,
+                              scratch_pool));
         }
 
       return SVN_NO_ERROR;
@@ -2790,6 +2794,12 @@ merge_dir_opened(void **new_dir_baton,
 
               db->tree_conflict_reason = added ? svn_wc_conflict_reason_added
                                                : svn_wc_conflict_reason_obstructed;
+
+              if ((merge_b->merge_source.ancestral || merge_b->reintegrate_merge)
+                  && !(pdb && pdb->shadowed))
+                {
+                  store_path(merge_b->skipped_abspaths, local_abspath);
+                }
             }
         }
 
@@ -2917,7 +2927,8 @@ merge_dir_changed(const char *relpath,
           /* We haven't notified for this node yet: report a skip */
           SVN_ERR(record_skip(merge_b, local_abspath, svn_node_dir,
                               svn_wc_notify_update_shadowed_update,
-                              db->skip_reason, scratch_pool));
+                              db->skip_reason, db->parent_baton,
+                              scratch_pool));
         }
 
       return SVN_NO_ERROR;
@@ -3002,7 +3013,8 @@ merge_dir_added(const char *relpath,
           /* We haven't notified for this node yet: report a skip */
           SVN_ERR(record_skip(merge_b, local_abspath, svn_node_dir,
                               svn_wc_notify_update_shadowed_add,
-                              db->skip_reason, scratch_pool));
+                              db->skip_reason, db->parent_baton,
+                              scratch_pool));
         }
 
       return SVN_NO_ERROR;
@@ -3169,7 +3181,8 @@ merge_dir_deleted(const char *relpath,
           /* We haven't notified for this node yet: report a skip */
           SVN_ERR(record_skip(merge_b, local_abspath, svn_node_dir,
                               svn_wc_notify_update_shadowed_delete,
-                              db->skip_reason, scratch_pool));
+                              db->skip_reason, db->parent_baton,
+                              scratch_pool));
         }
 
       return SVN_NO_ERROR;
@@ -3351,13 +3364,14 @@ merge_node_absent(const char *relpath,
                   apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = processor->baton;
+  struct merge_dir_baton_t *db = dir_baton;
 
   const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
                                               relpath, scratch_pool);
 
   SVN_ERR(record_skip(merge_b, local_abspath, svn_node_unknown,
                       svn_wc_notify_skip, svn_wc_notify_state_missing,
-                      scratch_pool));
+                      db, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/1.9.x/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1667834&r1=1667833&r2=1667834&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/1.9.x/subversion/tests/cmdline/merge_tree_conflict_tests.py Thu Mar 19 18:23:48 2015
@@ -2087,6 +2087,116 @@ def merge_conflict_details(sbox):
   svntest.actions.run_and_verify_info(expected_info, sbox.ospath('B'),
                                       '--depth', 'infinity')
 
+def merge_obstruction_recording(sbox):
+  "merge obstruction recording"
+
+  sbox.build(empty=True)
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_mkdir('trunk')
+  sbox.simple_mkdir('branches')
+  sbox.simple_commit() #r1
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', sbox.repo_url + '/trunk',
+                                     sbox.repo_url + '/branches/branch',
+                                     '-mCopy') # r2
+
+  sbox.simple_mkdir('trunk/dir')
+  sbox.simple_add_text('The file on trunk\n', 'trunk/dir/file.txt')
+  sbox.simple_commit() #r3
+
+  sbox.simple_update()
+
+  sbox.simple_mkdir('branches/branch/dir')
+  sbox.simple_add_text('The file on branch\n', 'branches/branch/dir/file.txt')
+  sbox.simple_commit() #r4
+
+  sbox.simple_update()
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                      'switch', '^/branches/branch', wc_dir,
+                                      '--ignore-ancestry')
+
+  expected_output = wc.State(wc_dir, {
+    'dir'          : Item(status='  ', treeconflict='C'),
+    'dir/file.txt' : Item(status='  ', treeconflict='A'),
+  })
+  expected_mergeinfo_output = wc.State(wc_dir, {
+    ''             : Item(status=' U'),
+    'dir'          : Item(status=' U'), # Because dir already exists
+  })
+  expected_elision_output = wc.State(wc_dir, {
+  })
+  expected_disk = wc.State('', {
+    'dir/file.txt' : Item(contents="The file on branch\n"),
+    'dir'          : Item(props={'svn:mergeinfo':''}),
+    '.'            : Item(props={'svn:mergeinfo':'/trunk:2-4'}),
+  })
+  expected_status = wc.State(wc_dir, {
+    ''             : Item(status=' M', wc_rev='4'),
+    'dir'          : Item(status=' M', treeconflict='C', wc_rev='4'),
+    'dir/file.txt' : Item(status='  ', wc_rev='4'),
+  })
+  expected_skip = wc.State('', {
+  })
+  svntest.actions.run_and_verify_merge(wc_dir, '1', '4', sbox.repo_url + '/trunk',
+                                       None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       check_props=True)
+  expected_info = [
+     {
+      "Path" : re.escape(sbox.ospath('dir')),
+      "Tree conflict": re.escape(
+          'local dir obstruction, incoming dir add upon merge' +
+          ' Source  left: (none) ^/trunk/dir@1' +
+          ' Source right: (dir) ^/trunk/dir@4')
+    },
+  ]
+
+  svntest.actions.run_and_verify_info(expected_info, sbox.ospath('dir'))
+
+  # How should the user handle this conflict?
+  # ### Would be nice if we could just accept mine (leave as is, fix mergeinfo)
+  # ### or accept theirs (delete what is here and insert copy
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'resolve', '--accept=working',
+                                     sbox.ospath('dir'))
+
+  # Redo the skipped merge as record only merge
+  expected_output = [
+    '--- Recording mergeinfo for merge of r4 into \'%s\':\n' % \
+            sbox.ospath('dir'),
+    ' G   %s\n' % sbox.ospath('dir'),
+  ]
+  # ### Why are r1-r3 not recorded?
+  # ### Guess: Because dir's history only exists since r4.
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'merge', '--record-only',
+                                     sbox.repo_url + '/trunk/dir',
+                                     sbox.ospath('dir'),
+                                     '-c', '1-4')
+
+  expected_disk = wc.State('', {
+    'dir'          : Item(props={'svn:mergeinfo':'/trunk/dir:4'}),
+    'dir/file.txt' : Item(contents="The file on branch\n"),
+    '.'            : Item(props={'svn:mergeinfo':'/trunk:2-4'}),
+  })
+  svntest.actions.verify_disk(wc_dir, expected_disk, check_props=True)
+
+  # Because r1-r3 are not recorded, the mergeinfo is not elided :(
+
+  # Even something like a two url merge wouldn't work, because dir
+  # didn't exist below trunk in r1 either.
+
+  # A resolver action could be smarter though...
+
+
 ########################################################################
 # Run the tests
 
@@ -2118,6 +2228,7 @@ test_list = [ None,
               merge_replace_causes_tree_conflict2,
               merge_replace_on_del_fails,
               merge_conflict_details,
+              merge_obstruction_recording,
              ]
 
 if __name__ == '__main__':