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

svn commit: r1440414 - in /subversion/trunk: subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_wc/ subversion/tests/libsvn_wc/ tools/dev/svnraisetreeconflict/

Author: philip
Date: Wed Jan 30 13:49:29 2013
New Revision: 1440414

URL: http://svn.apache.org/viewvc?rev=1440414&view=rev
Log:
Allow move-update to handle replaced nodes.  This change adds a path
to the moved-away conflict stored in ACTUAL_NODE and paves the way
for handling multiple moved-to at one local_relpath.

* subversion/libsvn_wc/conflicts.h
* subversion/libsvn_wc/conflicts.c
  (svn_wc__conflict_skel_add_tree_conflict): Add path parameter.
  (svn_wc__conflict_read_tree_conflict): Add path parameter.

* subversion/include/private/svn_wc_private.h
* subversion/libsvn_wc/tree_conflicts.c
  (svn_wc__add_tree_conflict): Add path parameter.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_base_moved_to): New.

* subversion/libsvn_wc/wc_db_private.h
  (svn_wc__db_op_depth_moved_to): New.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_op_depth_moved_to, svn_wc__db_base_moved_to): New.

* subversion/libsvn_wc/update_editor.c
  (check_tree_conflict): Raise a moved-away conflict for replaces that
   overlay a move, store the new path in the conflict.
  (delete_entry, add_directory, open_directory, add_file, open_file,
   change_file_prop): Pass NULL.

* subversion/libsvn_wc/wc_db_update_move.c
  (mark_tree_conflict, get_tc_info): Add path parameter.
  (check_tree_conflict): Use new functions.
  (tc_editor_add_directory, tc_editor_add_file, tc_editor_delete): Pass NULL.
  (update_moved_away_conflict_victim): Add path parameter, use new function.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_LOWEST_WORKING_NODE): Select moved-to.

* subversion/libsvn_wc/upgrade.c
  (svn_wc__upgrade_conflict_skel_from_raw): Pass NULL.

* subversion/libsvn_client/merge.c
  (tree_conflict): Add path parameter.
  (tree_conflict_on_add): Adjust call.
  (check_moved_away): Replace boolean parameter with path.
  (merge_file_changed, merge_file_deleted, merge_dir_opened,
   merge_dir_props_changed, merge_dir_deleted): Use path instead of boolean.

* tools/dev/svnraisetreeconflict/svnraisetreeconflict.c
  (raise_tree_conflict): Pass NULL.

* subversion/tests/libsvn_wc/conflict-data-test.c
  (test_read_write_tree_conflicts): Pass NULL.
  (test_serialize_tree_conflict): Pass and retrieve new path.

* subversion/tests/libsvn_wc/op-depth-test.c
  (layered_moved_to): New XFail test.
  (test_funcs): Mark move_replace as PASS, add new test.

Modified:
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/libsvn_wc/conflicts.c
    subversion/trunk/subversion/libsvn_wc/conflicts.h
    subversion/trunk/subversion/libsvn_wc/tree_conflicts.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/upgrade.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
    subversion/trunk/subversion/libsvn_wc/wc_db_private.h
    subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
    subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
    subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c

Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Wed Jan 30 13:49:29 2013
@@ -306,6 +306,7 @@ svn_wc__get_tree_conflict(const svn_wc_c
 svn_error_t *
 svn_wc__add_tree_conflict(svn_wc_context_t *wc_ctx,
                           const svn_wc_conflict_description2_t *conflict,
+                          const char *moved_away_op_root_abspath,
                           apr_pool_t *scratch_pool);
 
 /* Remove any tree conflict on victim @a victim_abspath using @a wc_ctx.

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Wed Jan 30 13:49:29 2013
@@ -765,7 +765,8 @@ tree_conflict(merge_cmd_baton_t *merge_b
               const char *victim_abspath,
               svn_node_kind_t node_kind,
               svn_wc_conflict_action_t action,
-              svn_wc_conflict_reason_t reason)
+              svn_wc_conflict_reason_t reason,
+              const char *moved_away_op_root_abspath)
 {
   const svn_wc_conflict_description2_t *existing_conflict;
   svn_error_t *err;
@@ -796,6 +797,7 @@ tree_conflict(merge_cmd_baton_t *merge_b
                                  &merge_b->merge_source, merge_b->target,
                                  merge_b->pool));
       SVN_ERR(svn_wc__add_tree_conflict(merge_b->ctx->wc_ctx, conflict,
+                                        moved_away_op_root_abspath,
                                         merge_b->pool));
 
       alloc_and_store_path(&merge_b->conflicted_paths, victim_abspath,
@@ -836,6 +838,7 @@ tree_conflict_on_add(merge_cmd_baton_t *
     {
       /* There is no existing tree conflict so it is safe to add one. */
       SVN_ERR(svn_wc__add_tree_conflict(merge_b->ctx->wc_ctx, conflict,
+                                        NULL,
                                         merge_b->pool));
 
       alloc_and_store_path(&merge_b->conflicted_paths, victim_abspath,
@@ -863,6 +866,7 @@ tree_conflict_on_add(merge_cmd_baton_t *
                                      merge_b->pool);
 
       SVN_ERR(svn_wc__add_tree_conflict(merge_b->ctx->wc_ctx, conflict,
+                                        NULL,
                                         merge_b->pool));
 
       alloc_and_store_path(&merge_b->conflicted_paths, victim_abspath,
@@ -1397,21 +1401,23 @@ prepare_merge_props_changed(const apr_ar
 
 /* Indicate in *MOVED_AWAY whether the node at LOCAL_ABSPATH was
  * moved away locally. Do not raise an error if the node at LOCAL_ABSPATH
- * does not exist. */
+ * does not exist.
+ *
+ * ### Currently this looks at the highest moved-to but should merge
+ * ### be looking at the lowest moved-to?  Or perhaps only the base
+ * ### moved-to? */
 static svn_error_t *
-check_moved_away(svn_boolean_t *moved_away,
+check_moved_away(const char **op_root_abspath,
                  svn_wc_context_t *wc_ctx,
                  const char *local_abspath,
                  apr_pool_t *scratch_pool)
 {
   const char *moved_to_abspath;
 
-  SVN_ERR(svn_wc__node_was_moved_away(&moved_to_abspath, NULL,
+  SVN_ERR(svn_wc__node_was_moved_away(&moved_to_abspath, op_root_abspath,
                                       wc_ctx, local_abspath,
                                       scratch_pool, scratch_pool));
   
-  *moved_away = (moved_to_abspath != NULL);
-
   return SVN_NO_ERROR;
 }
 
@@ -1731,8 +1737,8 @@ merge_file_changed(svn_wc_notify_state_t
      way svn_wc_merge5() can do the merge. */
   if (wc_kind != svn_node_file || is_deleted)
     {
-      svn_boolean_t moved_away;
       svn_wc_conflict_reason_t reason;
+      const char *moved_away_op_root_abspath = NULL;
 
       /* Maybe the node is excluded via depth filtering? */
 
@@ -1762,9 +1768,9 @@ merge_file_changed(svn_wc_notify_state_t
        */
       if (is_deleted)
         {
-          SVN_ERR(check_moved_away(&moved_away, ctx->wc_ctx,
+          SVN_ERR(check_moved_away(&moved_away_op_root_abspath, ctx->wc_ctx,
                                    local_abspath, scratch_pool));
-          if (moved_away)
+          if (moved_away_op_root_abspath)
             reason = svn_wc_conflict_reason_moved_away;
           else
             reason = svn_wc_conflict_reason_deleted;
@@ -1773,7 +1779,8 @@ merge_file_changed(svn_wc_notify_state_t
         reason = svn_wc_conflict_reason_missing;
 
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_file,
-                            svn_wc_conflict_action_edit, reason));
+                            svn_wc_conflict_action_edit, reason,
+                            moved_away_op_root_abspath));
       SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_file,
                                    scratch_pool));
       return SVN_NO_ERROR;
@@ -2234,15 +2241,15 @@ merge_file_deleted(svn_wc_notify_state_t
   if (kind != svn_node_file || is_deleted)
     {
       svn_wc_conflict_reason_t reason;
+      const char *moved_away_op_root_abspath = NULL;
 
       if (is_deleted)
         {
-          svn_boolean_t moved_away;
-
-          SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+          SVN_ERR(check_moved_away(&moved_away_op_root_abspath,
+                                   merge_b->ctx->wc_ctx,
                                    local_abspath, scratch_pool));
 
-          if (moved_away)
+          if (moved_away_op_root_abspath)
             reason = svn_wc_conflict_reason_moved_away;
           else
             reason = svn_wc_conflict_reason_deleted;
@@ -2251,7 +2258,8 @@ merge_file_deleted(svn_wc_notify_state_t
         reason = svn_wc_conflict_reason_missing;
 
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_file,
-                            svn_wc_conflict_action_delete, reason));
+                            svn_wc_conflict_action_delete, reason,
+                            moved_away_op_root_abspath));
 
       SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_dir,
                                    scratch_pool));
@@ -2289,7 +2297,7 @@ merge_file_deleted(svn_wc_notify_state_t
        */
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_file,
                             svn_wc_conflict_action_delete,
-                            svn_wc_conflict_reason_edited));
+                            svn_wc_conflict_reason_edited, NULL));
 
       SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_dir,
                                    scratch_pool));
@@ -2392,7 +2400,7 @@ merge_dir_opened(svn_boolean_t *tree_con
         {
           SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
                                 svn_wc_conflict_action_edit,
-                                svn_wc_conflict_reason_replaced));
+                                svn_wc_conflict_reason_replaced, NULL));
 
           *skip_children = TRUE;
           SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_dir,
@@ -2411,21 +2419,24 @@ merge_dir_opened(svn_boolean_t *tree_con
       else if (is_deleted || wc_kind == svn_node_none)
         {
           svn_wc_conflict_reason_t reason;
+          const char *moved_away_op_root_abspath = NULL;
 
           if (is_deleted)
             {
-              svn_boolean_t moved_away;
-
-              SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+              SVN_ERR(check_moved_away(&moved_away_op_root_abspath,
+                                       merge_b->ctx->wc_ctx,
                                        local_abspath, scratch_pool));
-              reason = moved_away ? svn_wc_conflict_reason_moved_away
-                                  : svn_wc_conflict_reason_deleted;
+              if (moved_away_op_root_abspath)
+                reason = svn_wc_conflict_reason_moved_away;
+              else
+                reason = svn_wc_conflict_reason_deleted;
             }
           else
             reason = svn_wc_conflict_reason_missing;
 
           SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
-                                svn_wc_conflict_action_edit, reason));
+                                svn_wc_conflict_action_edit, reason,
+                                moved_away_op_root_abspath));
 
           *skip = TRUE;
           *skip_children = TRUE;
@@ -2470,15 +2481,15 @@ merge_dir_props_changed(svn_wc_notify_st
   if (kind != svn_node_dir || is_deleted)
     {
       svn_wc_conflict_reason_t reason;
+      const char *moved_away_op_root_abspath = NULL;
 
       if (is_deleted)
         {
-          svn_boolean_t moved_away;
-
-          SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+          SVN_ERR(check_moved_away(&moved_away_op_root_abspath,
+                                   merge_b->ctx->wc_ctx,
                                    local_abspath, scratch_pool));
 
-          if (moved_away)
+          if (moved_away_op_root_abspath)
             reason = svn_wc_conflict_reason_moved_away;
           else
             reason = svn_wc_conflict_reason_deleted;
@@ -2487,7 +2498,8 @@ merge_dir_props_changed(svn_wc_notify_st
         reason = svn_wc_conflict_reason_missing;
 
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_file,
-                            svn_wc_conflict_action_edit, reason));
+                            svn_wc_conflict_action_edit, reason,
+                            moved_away_op_root_abspath));
 
       SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_dir,
                                    scratch_pool));
@@ -2792,15 +2804,15 @@ merge_dir_deleted(svn_wc_notify_state_t 
   if (kind != svn_node_dir || is_deleted)
     {
       svn_wc_conflict_reason_t reason;
+      const char *moved_away_op_root_abspath = NULL;
 
       if (is_deleted)
         {
-          svn_boolean_t moved_away;
-
-          SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+          SVN_ERR(check_moved_away(&moved_away_op_root_abspath,
+                                   merge_b->ctx->wc_ctx,
                                    local_abspath, scratch_pool));
 
-          if (moved_away)
+          if (moved_away_op_root_abspath)
             reason = svn_wc_conflict_reason_moved_away;
           else
             reason = svn_wc_conflict_reason_deleted;
@@ -2809,7 +2821,8 @@ merge_dir_deleted(svn_wc_notify_state_t 
         reason = svn_wc_conflict_reason_missing;
 
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
-                            svn_wc_conflict_action_delete, reason));
+                            svn_wc_conflict_action_delete, reason,
+                            moved_away_op_root_abspath));
 
       SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_file,
                                    scratch_pool));
@@ -2839,7 +2852,7 @@ merge_dir_deleted(svn_wc_notify_state_t 
        * files, or property changes). Flag a tree conflict. */
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
                             svn_wc_conflict_action_delete,
-                            svn_wc_conflict_reason_edited));
+                            svn_wc_conflict_reason_edited, NULL));
 
       SVN_ERR(record_tree_conflict(merge_b, local_abspath, svn_node_dir,
                                    scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Wed Jan 30 13:49:29 2013
@@ -537,6 +537,7 @@ svn_wc__conflict_skel_add_tree_conflict(
                                         const char *wri_abspath,
                                         svn_wc_conflict_reason_t local_change,
                                         svn_wc_conflict_action_t incoming_change,
+                                        const char *moved_away_op_root_abspath,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool)
 {
@@ -548,8 +549,25 @@ svn_wc__conflict_skel_add_tree_conflict(
 
   SVN_ERR_ASSERT(!tree_conflict); /* ### Use proper error? */
 
+  SVN_ERR_ASSERT((local_change != svn_wc_conflict_reason_moved_away
+                  && !moved_away_op_root_abspath)
+                 || moved_away_op_root_abspath); /* ### Use proper error? */
+
   tree_conflict = svn_skel__make_empty_list(result_pool);
 
+  if (local_change == svn_wc_conflict_reason_moved_away)
+    {
+      const char *moved_away_op_root_relpath;
+
+      SVN_ERR(svn_wc__db_to_relpath(&moved_away_op_root_relpath,
+                                    db, wri_abspath,
+                                    moved_away_op_root_abspath,
+                                    result_pool, scratch_pool));
+
+      svn_skel__prepend_str(moved_away_op_root_relpath, tree_conflict,
+                            result_pool);
+    }
+
   svn_skel__prepend_str(
                 svn_token__to_word(incoming_change_map, incoming_change),
                 tree_conflict, result_pool);
@@ -915,6 +933,7 @@ svn_wc__conflict_read_prop_conflict(cons
 svn_error_t *
 svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *local_change,
                                     svn_wc_conflict_action_t *incoming_change,
+                                    const char **moved_away_op_root_abspath,
                                     svn_wc__db_t *db,
                                     const char *wri_abspath,
                                     const svn_skel_t *conflict_skel,
@@ -923,6 +942,7 @@ svn_wc__conflict_read_tree_conflict(svn_
 {
   svn_skel_t *tree_conflict;
   const svn_skel_t *c;
+  svn_boolean_t is_moved_away = FALSE;
 
   SVN_ERR(conflict__get_conflict(&tree_conflict, conflict_skel,
                                  SVN_WC__CONFLICT_KIND_TREE));
@@ -944,6 +964,8 @@ svn_wc__conflict_read_tree_conflict(svn_
         *local_change = value;
       else
         *local_change = svn_wc_conflict_reason_edited;
+
+      is_moved_away = *local_change == svn_wc_conflict_reason_moved_away;
     }
   c = c->next;
 
@@ -957,6 +979,19 @@ svn_wc__conflict_read_tree_conflict(svn_
         *incoming_change = svn_wc_conflict_action_edit;
     }
 
+  c = c->next;
+
+  if (is_moved_away && moved_away_op_root_abspath)
+    {
+      const char *moved_away_op_root_relpath = apr_pstrmemdup(scratch_pool,
+                                                              c->data, c->len);
+
+      SVN_ERR(svn_wc__db_from_relpath(moved_away_op_root_abspath,
+                                      db, wri_abspath,
+                                      moved_away_op_root_relpath,
+                                      result_pool, scratch_pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -1973,6 +2008,7 @@ svn_wc__conflict_invoke_resolver(svn_wc_
 
       SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
                                                   &incoming_change,
+                                                  NULL,
                                                   db, local_abspath,
                                                   conflict_skel,
                                                   scratch_pool, scratch_pool));
@@ -2237,6 +2273,7 @@ svn_wc__read_conflicts(const apr_array_h
 
       SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
                                                   &incoming_change,
+                                                  NULL,
                                                   db, local_abspath,
                                                   conflict_skel,
                                                   scratch_pool, scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.h?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.h (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.h Wed Jan 30 13:49:29 2013
@@ -211,6 +211,7 @@ svn_wc__conflict_skel_add_tree_conflict(
                                         const char *wri_abspath,
                                         svn_wc_conflict_reason_t local_change,
                                         svn_wc_conflict_action_t incoming_change,
+                                        const char *moved_away_op_root_abspath,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool);
 
@@ -341,6 +342,7 @@ svn_wc__conflict_read_prop_conflict(cons
 svn_error_t *
 svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *local_change,
                                     svn_wc_conflict_action_t *incoming_change,
+                                    const char **moved_away_op_root_abspath,
                                     svn_wc__db_t *db,
                                     const char *wri_abspath,
                                     const svn_skel_t *conflict_skel,

Modified: subversion/trunk/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/tree_conflicts.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/tree_conflicts.c Wed Jan 30 13:49:29 2013
@@ -400,6 +400,7 @@ svn_wc__del_tree_conflict(svn_wc_context
 svn_error_t *
 svn_wc__add_tree_conflict(svn_wc_context_t *wc_ctx,
                           const svn_wc_conflict_description2_t *conflict,
+                          const char *moved_away_op_root_abspath,
                           apr_pool_t *scratch_pool)
 {
   svn_boolean_t existing_conflict;
@@ -432,6 +433,7 @@ svn_wc__add_tree_conflict(svn_wc_context
                                                   conflict->local_abspath,
                                                   conflict->reason,
                                                   conflict->action,
+                                                  moved_away_op_root_abspath,
                                                   scratch_pool, scratch_pool));
 
   switch(conflict->operation)

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed Jan 30 13:49:29 2013
@@ -1394,6 +1394,7 @@ check_tree_conflict(svn_skel_t **pconfli
   svn_wc_conflict_reason_t reason = SVN_WC_CONFLICT_REASON_NONE;
   svn_boolean_t modified = FALSE;
   svn_boolean_t all_mods_are_deletes = FALSE;
+  const char *moved_away_op_root_abspath = NULL;
 
   *pconflict = NULL;
 
@@ -1431,21 +1432,26 @@ check_tree_conflict(svn_skel_t **pconfli
           }
         else
           {
-            /* The node is locally replaced. */
-            reason = svn_wc_conflict_reason_replaced;
+            /* The node is locally replaced but could also be moved-away. */
+            SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL,
+                                             &moved_away_op_root_abspath,
+                                             eb->db, local_abspath,
+                                             scratch_pool, scratch_pool));
+            if (moved_away_op_root_abspath)
+              reason = svn_wc_conflict_reason_moved_away;
+            else
+              reason = svn_wc_conflict_reason_replaced;
           }
         break;
 
 
       case svn_wc__db_status_deleted:
         {
-          const char *moved_to_abspath;
-
-          SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
-                                           NULL, NULL, eb->db,
-                                           local_abspath,
+          SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL,
+                                           &moved_away_op_root_abspath,
+                                           eb->db, local_abspath,
                                            scratch_pool, scratch_pool));
-          if (moved_to_abspath)
+          if (moved_away_op_root_abspath)
             reason = svn_wc_conflict_reason_moved_away;
           else
             reason = svn_wc_conflict_reason_deleted;
@@ -1560,6 +1566,7 @@ check_tree_conflict(svn_skel_t **pconfli
                                                   eb->db, local_abspath,
                                                   reason,
                                                   action,
+                                                  moved_away_op_root_abspath,
                                                   result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
@@ -1795,7 +1802,7 @@ delete_entry(const char *path,
       apr_hash_set(pb->deletion_conflicts, apr_pstrdup(pb->pool, base),
                    APR_HASH_KEY_STRING, tree_conflict);
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                   eb->db, local_abspath,
                                                   tree_conflict,
                                                   scratch_pool, scratch_pool));
@@ -2051,7 +2058,7 @@ add_directory(const char *path,
           /* ### Should store the conflict in DB to allow reinstalling
              ### with theoretically more data in close_directory() */
 
-          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                       eb->db,
                                                       db->local_abspath,
                                                       tree_conflict,
@@ -2063,6 +2070,7 @@ add_directory(const char *path,
                                         tree_conflict,
                                         eb->db, db->local_abspath,
                                         reason, svn_wc_conflict_action_replace,
+                                        NULL,
                                         db->pool, db->pool));
 
           /* And now stop checking for conflicts here and just perform
@@ -2187,7 +2195,7 @@ add_directory(const char *path,
                                         tree_conflict,
                                         eb->db, db->local_abspath,
                                         svn_wc_conflict_reason_unversioned,
-                                        svn_wc_conflict_action_add,
+                                        svn_wc_conflict_action_add, NULL,
                                         db->pool, pool));
           db->edit_conflict = tree_conflict;
         }
@@ -2356,7 +2364,7 @@ open_directory(const char *path,
       db->edit_conflict = tree_conflict;
       /* Other modifications wouldn't be a tree conflict */
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                   eb->db, db->local_abspath,
                                                   tree_conflict,
                                                   db->pool, db->pool));
@@ -3136,7 +3144,7 @@ add_file(const char *path,
           /* ### Should store the conflict in DB to allow reinstalling
              ### with theoretically more data in close_directory() */
 
-          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                       eb->db,
                                                       fb->local_abspath,
                                                       tree_conflict,
@@ -3148,6 +3156,7 @@ add_file(const char *path,
                                         tree_conflict,
                                         eb->db, fb->local_abspath,
                                         reason, svn_wc_conflict_action_replace,
+                                        NULL,
                                         fb->pool, fb->pool));
 
           /* And now stop checking for conflicts here and just perform
@@ -3270,6 +3279,7 @@ add_file(const char *path,
                                         eb->db, fb->local_abspath,
                                         svn_wc_conflict_reason_unversioned,
                                         svn_wc_conflict_action_add,
+                                        NULL,
                                         fb->pool, scratch_pool));
         }
     }
@@ -3419,7 +3429,7 @@ open_file(const char *path,
       fb->edit_conflict = tree_conflict;
       /* Other modifications wouldn't be a tree conflict */
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                   eb->db, fb->local_abspath,
                                                   tree_conflict,
                                                   scratch_pool, scratch_pool));
@@ -3655,6 +3665,7 @@ change_file_prop(void *file_baton,
                                      eb->db, fb->local_abspath,
                                      svn_wc_conflict_reason_edited,
                                      svn_wc_conflict_action_replace,
+                                     NULL,
                                      fb->pool, scratch_pool));
 
           SVN_ERR(complete_conflict(fb->edit_conflict, fb->dir_baton,

Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Wed Jan 30 13:49:29 2013
@@ -1457,6 +1457,7 @@ svn_wc__upgrade_conflict_skel_from_raw(s
                                                       db, wri_abspath,
                                                       tc->reason,
                                                       tc->action,
+                                                      NULL,
                                                       scratch_pool,
                                                       scratch_pool));
 

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Jan 30 13:49:29 2013
@@ -96,7 +96,7 @@ FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
 
 -- STMT_SELECT_LOWEST_WORKING_NODE
-SELECT op_depth, presence, kind
+SELECT op_depth, presence, kind, moved_to
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3
 ORDER BY op_depth

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Jan 30 13:49:29 2013
@@ -11527,6 +11527,133 @@ svn_wc__db_scan_deletion(const char **ba
   return SVN_NO_ERROR;
 }
 
+/* Extract the moved-to information for LOCAL_RELPATH at OP-DEPTH by
+   examining the lowest working node above OP_DEPTH.  The output paths
+   are NULL if there is no move, otherwise:
+
+   *MOVED_TO_RELPATH: the moved-to destination of LOCAL_RELPATH.
+
+   *MOVED_TO_OP_ROOT_RELPATH: the moved-to destination of the root of
+   the move of LOCAL_RELPATH. This may be equal to *MOVED_TO_RELPATH
+   if LOCAL_RELPATH is the root of the move.
+
+   *OP_ROOT_RELPATH: the root of the source layer that contains the
+   move.  For moves inside deletes this is the root of the delete, for
+   other moves this is the root of the move.
+
+   Given a path A/B/C with A/B moved to X then for A/B/C
+
+     MOVED_TO_RELPATH is X/C
+     MOVED_TO_OP_ROOT_RELPATH is X
+     OP_ROOT_RELPATH is A/B
+
+   If A is then deleted the MOVED_TO_RELPATH and MOVED_TO_OP_ROOT_RELPATH
+   remain the same but OP_ROOT_RELPATH changes to A.
+
+   ### Think about combining with scan_deletion?  Also with
+   ### scan_addition to get moved-to for replaces?  Do we need to
+   ### return the op-root of the move source, i.e. A/B in the example
+   ### above?  */
+svn_error_t *
+svn_wc__db_op_depth_moved_to(const char **moved_to_relpath,
+                             const char **moved_to_op_root_relpath,
+                             const char **op_root_relpath,
+                             int op_depth,
+                             svn_wc__db_wcroot_t *wcroot,
+                             const char *local_relpath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  int delete_op_depth;
+  const char *relpath = local_relpath;
+
+  *moved_to_relpath = *moved_to_op_root_relpath = *op_root_relpath = NULL;
+
+  do
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_LOWEST_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, relpath, op_depth));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      if (have_row)
+        {
+          delete_op_depth = svn_sqlite__column_int(stmt, 0);
+          *moved_to_op_root_relpath = svn_sqlite__column_text(stmt, 3,
+                                                              result_pool);
+        }
+      SVN_ERR(svn_sqlite__reset(stmt));
+      if (!*moved_to_op_root_relpath)
+        relpath = svn_relpath_dirname(relpath, scratch_pool);
+    }
+  while(!*moved_to_op_root_relpath
+        && have_row && delete_op_depth < relpath_depth(relpath));
+
+  if (*moved_to_op_root_relpath)
+    {
+      *moved_to_relpath
+        = svn_relpath_join(*moved_to_op_root_relpath,
+                           svn_relpath_skip_ancestor(relpath, local_relpath),
+                           result_pool);
+      while(delete_op_depth < relpath_depth(relpath))
+        relpath = svn_relpath_dirname(relpath, scratch_pool);
+      *op_root_relpath = apr_pstrdup(result_pool, relpath);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Public (within libsvn_wc) absolute path version of
+   svn_wc__db_op_depth_moved_to with the op-depth hard-coded to
+   BASE. */
+svn_error_t *
+svn_wc__db_base_moved_to(const char **moved_to_abspath,
+                         const char **moved_to_op_root_abspath,
+                         const char **op_root_abspath,
+                         svn_wc__db_t *db,
+                         const char *local_abspath,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  const char *moved_to_relpath, *moved_to_op_root_relpath, *op_root_relpath;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  SVN_WC__DB_WITH_TXN(svn_wc__db_op_depth_moved_to(&moved_to_relpath,
+                                                   &moved_to_op_root_relpath,
+                                                   &op_root_relpath,
+                                                   0 /* BASE op-depth */,
+                                                   wcroot, local_relpath,
+                                                   scratch_pool, scratch_pool),
+                      wcroot);
+
+  if (moved_to_abspath)
+    *moved_to_abspath
+      = moved_to_relpath
+      ? svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool)
+      : NULL;
+
+  if (moved_to_op_root_abspath)
+    *moved_to_op_root_abspath
+      = moved_to_op_root_relpath
+      ? svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool)
+      : NULL;
+
+  if (op_root_abspath)
+    *op_root_abspath
+      = op_root_relpath
+      ? svn_dirent_join(wcroot->abspath, op_root_relpath, result_pool)
+      : NULL;
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Jan 30 13:49:29 2013
@@ -3271,6 +3271,15 @@ svn_wc__db_update_moved_away_conflict_vi
                                              apr_pool_t *result_pool,
                                              apr_pool_t *scratch_pool);
 
+svn_error_t *
+svn_wc__db_base_moved_to(const char **moved_to_abspath,
+                         const char **moved_to_op_root_abspath,
+                         const char **op_root_abspath,
+                         svn_wc__db_t *db,
+                         const char *local_abspath,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
+                         
 /* Recover space from the database file for LOCAL_ABSPATH by running
  * the "vacuum" command. */
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_private.h?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_private.h Wed Jan 30 13:49:29 2013
@@ -421,6 +421,16 @@ svn_wc__db_retract_parent_delete(svn_wc_
                                  int op_depth,
                                  apr_pool_t *scratch_pool);
 
+svn_error_t *
+svn_wc__db_op_depth_moved_to(const char **moved_to_relpath,
+                             const char **moved_to_op_root_relpath,
+                             const char **op_root_relpath,
+                             int op_depth,
+                             svn_wc__db_wcroot_t *wcroot,
+                             const char *local_relpath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
+
 /* Do a post-drive revision bump for the moved-away destination for
    any move sources under LOCAL_RELPATH.  This is called from within
    the revision bump transaction after the tree at LOCAL_RELPATH has

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Wed Jan 30 13:49:29 2013
@@ -218,11 +218,17 @@ mark_tree_conflict(struct tc_editor_bato
                    svn_node_kind_t new_kind,
                    svn_wc_conflict_reason_t reason,
                    svn_wc_conflict_action_t action,
+                   const char *moved_away_op_root_relpath,
                    svn_skel_t *conflict,
                    apr_pool_t *scratch_pool)
 {
   const char *repos_relpath;
   svn_wc_conflict_version_t *old_version, *new_version;
+  const char *moved_away_op_root_abspath
+    = moved_away_op_root_relpath
+    ? svn_dirent_join(b->wcroot->abspath,
+                      moved_away_op_root_relpath, scratch_pool)
+    : NULL;
 
   if (!conflict)
     conflict = svn_wc__conflict_skel_create(scratch_pool);
@@ -230,11 +236,12 @@ mark_tree_conflict(struct tc_editor_bato
   b->conflict_root_relpath = apr_pstrdup(b->result_pool, local_relpath);
 
   SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
-                     conflict, NULL,
+                     conflict, b->db,
                      svn_dirent_join(b->wcroot->abspath, local_relpath,
                                      scratch_pool),
                      reason,
                      action,
+                     moved_away_op_root_abspath,
                      scratch_pool,
                      scratch_pool));
 
@@ -305,7 +312,8 @@ check_tree_conflict(svn_boolean_t *is_co
   int op_depth;
   svn_node_kind_t old_kind;
   const char *conflict_root_relpath = local_relpath;
-  const char *moved_to_relpath;
+  const char *moved_to_relpath, *moved_to_op_root_relpath;
+  const char *moved_away_op_root_relpath;
   svn_skel_t *conflict;
 
   if (b->conflict_root_relpath)
@@ -354,7 +362,7 @@ check_tree_conflict(svn_boolean_t *is_co
   if (conflict)
     {
       svn_error_t *err
-        = svn_wc__conflict_read_tree_conflict(NULL, NULL, 
+        = svn_wc__conflict_read_tree_conflict(NULL, NULL, NULL,
                                               b->db, b->wcroot->abspath,
                                               conflict,
                                               scratch_pool, scratch_pool);
@@ -369,17 +377,19 @@ check_tree_conflict(svn_boolean_t *is_co
       svn_error_clear(err);
     }
 
-  SVN_ERR(svn_wc__db_scan_deletion_internal(NULL, &moved_to_relpath,
-                                            NULL, NULL,
-                                            b->wcroot, conflict_root_relpath,
-                                            scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_op_depth_moved_to(&moved_to_relpath,
+                                       &moved_to_op_root_relpath,
+                                       &moved_away_op_root_relpath,
+                                       dst_op_depth,
+                                       b->wcroot, conflict_root_relpath,
+                                       scratch_pool, scratch_pool));
 
   SVN_ERR(mark_tree_conflict(b, conflict_root_relpath, old_kind, kind,
                              (moved_to_relpath
                               ? svn_wc_conflict_reason_moved_away
                               : svn_wc_conflict_reason_deleted),
-                             action, conflict,
-                             scratch_pool));
+                             action, moved_away_op_root_relpath,
+                             conflict, scratch_pool));
   if (b->notify_func)
     SVN_ERR(update_move_list_add(b->wcroot, local_relpath,
                                  svn_wc_notify_tree_conflict,
@@ -428,7 +438,7 @@ tc_editor_add_directory(void *baton,
     default:
       SVN_ERR(mark_tree_conflict(b, relpath, kind, svn_node_dir,
                                  svn_wc_conflict_reason_unversioned,
-                                 svn_wc_conflict_action_add, NULL,
+                                 svn_wc_conflict_action_add, NULL, NULL,
                                  scratch_pool));
       action = svn_wc_notify_tree_conflict;
       break;
@@ -489,7 +499,7 @@ tc_editor_add_file(void *baton,
     {
       SVN_ERR(mark_tree_conflict(b, relpath, kind, svn_node_file,
                                  svn_wc_conflict_reason_unversioned,
-                                 svn_wc_conflict_action_add, NULL,
+                                 svn_wc_conflict_action_add, NULL, NULL,
                                  scratch_pool));
       if (b->notify_func)
         SVN_ERR(update_move_list_add(b->wcroot, relpath,
@@ -990,7 +1000,7 @@ tc_editor_delete(void *baton,
           SVN_ERR(mark_tree_conflict(b, relpath,
                                      /* ### kinds? */
                                      svn_node_dir, svn_node_dir, reason,
-                                     svn_wc_conflict_action_delete, NULL,
+                                     svn_wc_conflict_action_delete, NULL, NULL,
                                      scratch_pool));
           if (b->notify_func)
             SVN_ERR(update_move_list_add(b->wcroot, relpath,
@@ -1195,6 +1205,7 @@ static svn_error_t *
 get_tc_info(svn_wc_operation_t *operation,
             svn_wc_conflict_reason_t *local_change,
             svn_wc_conflict_action_t *incoming_change,
+            const char **moved_away_op_root_abspath,
             svn_wc_conflict_version_t **old_version,
             svn_wc_conflict_version_t **new_version,
             svn_wc__db_t *db,
@@ -1239,6 +1250,7 @@ get_tc_info(svn_wc_operation_t *operatio
 
   SVN_ERR(svn_wc__conflict_read_tree_conflict(local_change,
                                               incoming_change,
+                                              moved_away_op_root_abspath,
                                               db, src_abspath,
                                               conflict_skel, scratch_pool,
                                               scratch_pool));
@@ -1615,6 +1627,7 @@ update_moved_away_conflict_victim(svn_sk
                                   svn_wc_operation_t operation,
                                   svn_wc_conflict_reason_t local_change,
                                   svn_wc_conflict_action_t incoming_change,
+                                  const char *moved_away_op_root_relpath,
                                   svn_wc_conflict_version_t *old_version,
                                   svn_wc_conflict_version_t *new_version,
                                   svn_wc_notify_func2_t notify_func,
@@ -1628,14 +1641,16 @@ update_moved_away_conflict_victim(svn_sk
   struct tc_editor_baton *tc_editor_baton;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+  const char *dummy1, *dummy2;
   int src_op_depth;
 
   /* ### assumes wc write lock already held */
 
   /* Construct editor baton. */
   tc_editor_baton = apr_pcalloc(scratch_pool, sizeof(*tc_editor_baton));
-  SVN_ERR(svn_wc__db_scan_deletion_internal(
-            NULL, &tc_editor_baton->move_root_dst_relpath, NULL, NULL,
+  SVN_ERR(svn_wc__db_op_depth_moved_to(
+            &dummy1, &tc_editor_baton->move_root_dst_relpath, &dummy2,
+            relpath_depth(moved_away_op_root_relpath) - 1,
             wcroot, victim_relpath, scratch_pool, scratch_pool));
   if (tc_editor_baton->move_root_dst_relpath == NULL)
     return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
@@ -1654,7 +1669,7 @@ update_moved_away_conflict_victim(svn_sk
   tc_editor_baton->notify_baton = notify_baton;
   tc_editor_baton->result_pool = result_pool;
 
-  /* ### TODO get from svn_wc__db_scan_deletion_internal? */
+  /* ### TODO get from svn_wc__db_op_depth_moved_to? */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_NODE_INFO));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, victim_relpath));
@@ -1716,8 +1731,10 @@ svn_wc__db_update_moved_away_conflict_vi
   svn_wc_conflict_action_t incoming_change;
   svn_wc_conflict_version_t *old_version;
   svn_wc_conflict_version_t *new_version;
+  const char *moved_away_op_root_abspath, *moved_away_op_root_relpath;
 
   SVN_ERR(get_tc_info(&operation, &local_change, &incoming_change,
+                      &moved_away_op_root_abspath,
                       &old_version, &new_version,
                       db, victim_abspath,
                       scratch_pool, scratch_pool));
@@ -1727,10 +1744,14 @@ svn_wc__db_update_moved_away_conflict_vi
                                                 scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
+  moved_away_op_root_relpath
+    = svn_dirent_skip_ancestor(wcroot->abspath, moved_away_op_root_abspath);
+
   SVN_WC__DB_WITH_TXN(
     update_moved_away_conflict_victim(
       work_items, db, wcroot, local_relpath,
       operation, local_change, incoming_change,
+      moved_away_op_root_relpath,
       old_version, new_version,
       notify_func, notify_baton,
       cancel_func, cancel_baton,

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=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/conflict-data-test.c Wed Jan 30 13:49:29 2013
@@ -229,9 +229,9 @@ test_read_write_tree_conflicts(const svn
 
   /* Write */
   SVN_ERR(svn_wc__add_tree_conflict(sbox.wc_ctx, /*child1_abspath,*/
-                                    conflict1, pool));
+                                    conflict1, NULL, pool));
   SVN_ERR(svn_wc__add_tree_conflict(sbox.wc_ctx, /*child2_abspath,*/
-                                    conflict2, pool));
+                                    conflict2, NULL, pool));
 
   /* Query (conflict1 through WC-DB API, conflict2 through WC API) */
   {
@@ -501,9 +501,10 @@ test_serialize_tree_conflict(const svn_t
 
   SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                               conflict_skel,
-                              sbox.wc_ctx->db, sbox.wc_abspath,
+                              sbox.wc_ctx->db, sbox_wc_path(&sbox, "A/B"),
                               svn_wc_conflict_reason_moved_away,
                               svn_wc_conflict_action_delete,
+                              sbox_wc_path(&sbox, "A/B"),
                               pool, pool));
 
   SVN_ERR(svn_wc__conflict_skel_set_op_switch(
@@ -520,9 +521,11 @@ test_serialize_tree_conflict(const svn_t
   {
     svn_wc_conflict_reason_t local_change;
     svn_wc_conflict_action_t incoming_change;
+    const char *moved_away_op_root_abspath;
 
     SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
                                                 &incoming_change,
+                                                &moved_away_op_root_abspath,
                                                 sbox.wc_ctx->db,
                                                 sbox.wc_abspath,
                                                 conflict_skel,
@@ -530,6 +533,8 @@ test_serialize_tree_conflict(const svn_t
 
     SVN_TEST_ASSERT(local_change == svn_wc_conflict_reason_moved_away);
     SVN_TEST_ASSERT(incoming_change == svn_wc_conflict_action_delete);
+    SVN_TEST_ASSERT(!strcmp(moved_away_op_root_abspath,
+                            sbox_wc_path(&sbox, "A/B")));
   }
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Wed Jan 30 13:49:29 2013
@@ -6023,6 +6023,87 @@ move_replace(const svn_test_opts_t *opts
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+layered_moved_to(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "layered_moved_to", opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "B/C"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_propset(&b, "property", "value", "A/B/C"));
+  SVN_ERR(sbox_wc_propset(&b, "property", "value", "B/C"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+
+  SVN_ERR(sbox_wc_move(&b, "A", "X"));
+  SVN_ERR(sbox_wc_move(&b, "X/B/C", "C2"));
+  SVN_ERR(sbox_wc_delete(&b, "X/B"));
+  SVN_ERR(sbox_wc_move(&b, "B", "X/B"));
+  SVN_ERR(sbox_wc_move(&b, "X/B/C", "C3"));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A"},
+      {0, "A/B",     "normal",       1, "A/B"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {0, "B",       "normal",       1, "B"},
+      {0, "B/C",     "normal",       1, "B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM, "X"},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "B",       "base-deleted", NO_COPY_FROM, "X/B"},
+      {1, "B/C",     "base-deleted", NO_COPY_FROM},
+      {1, "X",       "normal",       1, "A", MOVED_HERE},
+      {1, "X/B",     "normal",       1, "A/B", MOVED_HERE},
+      {1, "X/B/C",   "normal",       1, "A/B/C", MOVED_HERE},
+      {2, "X/B",     "normal",       1, "B", MOVED_HERE},
+      {2, "X/B/C",   "normal",       1, "B/C", FALSE, "C2", TRUE},
+      {3, "X/B/C",   "base-deleted", NO_COPY_FROM, "C3"},
+      {1, "C2",      "normal",       1, "A/B/C", MOVED_HERE},
+      {1, "C3",      "normal",       1, "B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_update(&b, "A", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "X/B", svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "X/B/C", svn_wc_conflict_choose_mine_conflict));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       2, "A"},
+      {0, "A/B",     "normal",       2, "A/B"},
+      {0, "A/B/C",   "normal",       2, "A/B/C"},
+      {0, "B",       "normal",       1, "B"},
+      {0, "B/C",     "normal",       1, "B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM, "X"},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "B",       "base-deleted", NO_COPY_FROM, "X/B"},
+      {1, "B/C",     "base-deleted", NO_COPY_FROM},
+      {1, "X",       "normal",       2, "A", MOVED_HERE},
+      {1, "X/B",     "normal",       2, "A/B", MOVED_HERE},
+      {1, "X/B/C",   "normal",       2, "A/B/C", MOVED_HERE},
+      {2, "X/B",     "normal",       1, "B", MOVED_HERE},
+      {2, "X/B/C",   "normal",       1, "B/C", FALSE, "C2", TRUE},
+      {3, "X/B/C",   "base-deleted", NO_COPY_FROM, "C3"},
+      {1, "C2",      "normal",       2, "A/B/C", MOVED_HERE},
+      {1, "C3",      "normal",       1, "B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
 
   return SVN_NO_ERROR;
 }
@@ -6141,7 +6222,9 @@ struct svn_test_descriptor_t test_funcs[
                        "move_in_delete (issue 4303)"),
     SVN_TEST_OPTS_PASS(switch_move,
                        "switch_move"),
-    SVN_TEST_OPTS_XFAIL(move_replace,
+    SVN_TEST_OPTS_PASS(move_replace,
                        "move_replace"),
+    SVN_TEST_OPTS_XFAIL(layered_moved_to,
+                       "layered_moved_to"),
     SVN_TEST_NULL
   };

Modified: subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c?rev=1440414&r1=1440413&r2=1440414&view=diff
==============================================================================
--- subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c (original)
+++ subversion/trunk/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c Wed Jan 30 13:49:29 2013
@@ -229,7 +229,7 @@ raise_tree_conflict(int argc, const char
 
   /* Raise the conflict */
   SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
-  SVN_ERR(svn_wc__add_tree_conflict(wc_ctx, c, pool));
+  SVN_ERR(svn_wc__add_tree_conflict(wc_ctx, c, NULL, pool));
 
   return SVN_NO_ERROR;
 }