Author: stsp
Date: Thu Aug 21 14:51:35 2014
New Revision: 1619418

URL: http://svn.apache.org/r1619418
Log:
Fix misreporting of tree conflict victim's node kind, in particular
in cases where the victim is an obstruction.

* subversion/libsvn_wc/conflicts.c
  (read_tree_conflict_desc): The local node kind cannot be derived from the
   incoming src-left or src-right node kind as was done here. For example,
   local unversioned files were labeled as 'local dir' if they obstructed
   an incoming directory addition. If the conflict reason is an obstruction
   we must check the on-disk state of the node and use it to describe the
   victim's node kind. Missing nodes obviously have node type 'none' but
   they were described as 'file'.

* subversion/svn/cl-conflicts.c
  (local_reason_str, incoming_action_str): Describe symlinks as files.
   Handle 'none' and 'unknown' type nodes.

* subversion/tests/cmdline/switch_tests.py
  (forced_switch_failures): This test had node kinds swapped around. Fix it.

* subversion/tests/cmdline/tree_conflict_tests.py
  (actual_only_node_behaviour): Output for 'none' type nodes has changed.
   Adjust expected output accordingly.

Modified:
    subversion/trunk/subversion/libsvn_wc/conflicts.c
    subversion/trunk/subversion/svn/cl-conflicts.c
    subversion/trunk/subversion/tests/cmdline/switch_tests.py
    subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
    subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1619418&r1=1619417&r2=1619418&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Thu Aug 21 14:51:35 2014
@@ -1798,7 +1798,7 @@ read_tree_conflict_desc(svn_wc_conflict_
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
-  svn_node_kind_t tc_kind;
+  svn_node_kind_t local_kind;
   svn_wc_conflict_reason_t reason;
   svn_wc_conflict_action_t action;
 
@@ -1806,14 +1806,42 @@ read_tree_conflict_desc(svn_wc_conflict_
             &reason, &action, NULL,
             db, local_abspath, conflict_skel, scratch_pool, scratch_pool));
 
-  if (left_version)
-    tc_kind = left_version->node_kind;
-  else if (right_version)
-    tc_kind = right_version->node_kind;
+  if (reason == svn_wc_conflict_reason_missing)
+    local_kind = svn_node_none;
+  else if (reason == svn_wc_conflict_reason_unversioned ||
+           reason == svn_wc_conflict_reason_obstructed)
+    SVN_ERR(svn_io_check_path(local_abspath, &local_kind, scratch_pool));
+  else if (operation == svn_wc_operation_merge)
+    {
+      /* Read the tree conflict victim's node kind from the working
+       * or base tree. */
+      SVN_ERR(svn_wc__db_read_kind(&local_kind, db, local_abspath,
+                                   TRUE, TRUE, TRUE, scratch_pool));
+      if (local_kind == svn_node_unknown)
+        SVN_ERR(svn_io_check_path(local_abspath, &local_kind, scratch_pool));
+    }
+  else if (operation == svn_wc_operation_update ||
+           operation == svn_wc_operation_switch)
+    {
+      /* For updates, the left version corresponds to the pre-update state. */
+      if (left_version)
+        local_kind = left_version->node_kind;
+      else
+        {
+          /* No left version is available, so the conflict was flagged
+           * because of a locally added node which was not part of the
+           * BASE tree before the update. */
+          SVN_ERR(svn_wc__db_read_kind(&local_kind, db, local_abspath,
+                                       TRUE, TRUE, TRUE, scratch_pool));
+          if (local_kind == svn_node_unknown)
+            SVN_ERR(svn_io_check_path(local_abspath, &local_kind,
+                                      scratch_pool));
+        }
+    }
   else
-    tc_kind = svn_node_file; /* Avoid assertion */
+    SVN_ERR_MALFUNCTION();
 
-  *desc = svn_wc_conflict_description_create_tree2(local_abspath, tc_kind,
+  *desc = svn_wc_conflict_description_create_tree2(local_abspath, local_kind,
                                                    operation,
                                                    left_version, right_version,
                                                    result_pool);

Modified: subversion/trunk/subversion/svn/cl-conflicts.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl-conflicts.c?rev=1619418&r1=1619417&r2=1619418&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl-conflicts.c (original)
+++ subversion/trunk/subversion/svn/cl-conflicts.c Thu Aug 21 14:51:35 2014
@@ -75,6 +75,7 @@ local_reason_str(svn_node_kind_t kind, s
   switch (kind)
     {
       case svn_node_file:
+      case svn_node_symlink:
         switch (reason)
           {
           case svn_wc_conflict_reason_edited:
@@ -126,9 +127,32 @@ local_reason_str(svn_node_kind_t kind, s
             return _("local dir moved here");
           }
         break;
-      case svn_node_symlink:
       case svn_node_none:
       case svn_node_unknown:
+        switch (reason)
+          {
+          case svn_wc_conflict_reason_edited:
+            return _("local edit");
+          case svn_wc_conflict_reason_obstructed:
+            return _("local obstruction");
+          case svn_wc_conflict_reason_deleted:
+            return _("local delete");
+          case svn_wc_conflict_reason_missing:
+            if (operation == svn_wc_operation_merge)
+              return _("local deleted or moved away");
+            else
+              return _("local missing");
+          case svn_wc_conflict_reason_unversioned:
+            return _("local unversioned");
+          case svn_wc_conflict_reason_added:
+            return _("local add");
+          case svn_wc_conflict_reason_replaced:
+            return _("local replace");
+          case svn_wc_conflict_reason_moved_away:
+            return _("local moved away");
+          case svn_wc_conflict_reason_moved_here:
+            return _("local moved here");
+          }
         break;
     }
   return NULL;
@@ -142,6 +166,7 @@ incoming_action_str(svn_node_kind_t kind
   switch (kind)
     {
       case svn_node_file:
+      case svn_node_symlink:
         switch (action)
           {
             case svn_wc_conflict_action_edit:
@@ -167,9 +192,19 @@ incoming_action_str(svn_node_kind_t kind
               return _("incoming dir replace");
           }
         break;
-      case svn_node_symlink:
       case svn_node_none:
       case svn_node_unknown:
+        switch (action)
+          {
+            case svn_wc_conflict_action_edit:
+              return _("incoming edit");
+            case svn_wc_conflict_action_add:
+              return _("incoming add");
+            case svn_wc_conflict_action_delete:
+              return _("incoming delete or move");
+            case svn_wc_conflict_action_replace:
+              return _("incoming replace");
+          }
         break;
     }
   return NULL;

Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=1619418&r1=1619417&r2=1619418&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Thu Aug 21 
14:51:35 2014
@@ -1025,8 +1025,8 @@ def forced_switch_failures(sbox):
   main.file_write(A_C_H, "The file 'H'\n")
 
   # Test three cases where forced switch should cause a tree conflict
-  # 1) A forced switch that tries to add a file when an unversioned
-  #    directory of the same name already exists.  (Currently fails)
+  # 1) A forced switch that tries to add a directory when an unversioned
+  #    file of the same name already exists.  (Currently fails)
   # svn switch --force url/A/D A/C
   expected_output = svntest.wc.State(wc_dir, {
     'A/C/G'             : Item(status='A '),
@@ -1071,7 +1071,7 @@ def forced_switch_failures(sbox):
                                 '--ignore-ancestry')
 
 
-  # 2) A forced switch that tries to add a dir when a file of the same
+  # 2) A forced switch that tries to add a file when a dir of the same
   #    name already exists. (Tree conflict)
   # svn switch --force url/A/D/G A/B/F
   expected_output = svntest.wc.State(wc_dir, {
@@ -1099,7 +1099,7 @@ def forced_switch_failures(sbox):
 
   # svn info A/B/F/pi
   expected_stdout = verify.ExpectedOutput(
-    'Tree conflict: local file unversioned, incoming file add upon switch\n',
+    'Tree conflict: local dir unversioned, incoming file add upon switch\n',
     match_all=False)
 
   actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'info',

Modified: subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py?rev=1619418&r1=1619417&r2=1619418&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py Thu Aug 21 
14:51:35 2014
@@ -1258,7 +1258,7 @@ def actual_only_node_behaviour(sbox):
 
   # info
   expected_info = {
-    'Tree conflict': 'local file missing or deleted or moved away, incoming 
file edit upon merge.*',
+    'Tree conflict': 'local deleted or moved away, incoming file edit upon 
merge.*',
     'Name': 'foo',
     'Schedule': 'normal',
     'Node Kind': 'none',

Modified: subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c?rev=1619418&r1=1619417&r2=1619418&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c Thu Aug 21 
14:51:35 2014
@@ -289,10 +289,11 @@ test_read_write_tree_conflicts(const svn
 
   SVN_ERR(svn_test__sandbox_create(&sbox, "read_write_tree_conflicts", opts, 
pool));
   parent_abspath = svn_dirent_join(sbox.wc_abspath, "A", pool);
-  SVN_ERR(svn_wc__db_op_add_directory(sbox.wc_ctx->db, parent_abspath,
-                                      NULL /*props*/, NULL, pool));
   child1_abspath = svn_dirent_join(parent_abspath, "foo", pool);
   child2_abspath = svn_dirent_join(parent_abspath, "bar", pool);
+  SVN_ERR(sbox_wc_mkdir(&sbox, "A"));
+  SVN_ERR(sbox_wc_mkdir(&sbox, "A/bar"));
+  sbox_file_write(&sbox, "A/foo", "");
 
   conflict1 = tree_conflict_create(child1_abspath, svn_node_file,
                                    svn_wc_operation_merge,


Reply via email to