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/11 20:06:47 UTC

svn commit: r1432233 - in /subversion/trunk/subversion: libsvn_wc/wc_db_update_move.c tests/libsvn_wc/op-depth-test.c tests/libsvn_wc/utils.c tests/libsvn_wc/utils.h

Author: philip
Date: Fri Jan 11 19:06:47 2013
New Revision: 1432233

URL: http://svn.apache.org/viewvc?rev=1432233&view=rev
Log:
Move updating is relying on a non-Ev2, depth-first, drive to raise
the right tree-conflicts so make it explicit, also test that we are
generating conflicts with the correct repository path.

* subversion/libsvn_wc/wc_db_update_move.c
  (struct tc_editor_baton): Add conflict_root_relpath member.
  (mark_tree_conflict): Remove conflict_root_relpath parameter, store
   conflict path.
  (check_tree_conflict): Check most recent tree-conflict, correct
   old kind when moving to the parent, adjust call to mark_tree_conflict.
  (tc_editor_add_directory, tc_editor_add_file): Adjust call to
   mark_tree_conflict.
  (tc_editor_alter_file, update_moved_away_dir,
   update_moved_away_subtree): Tweak comments.

* subversion/tests/libsvn_wc/utils.h
  (sbox_wc_switch): New.

* subversion/tests/libsvn_wc/utils.c
  (sbox_wc_switch): New.

* subversion/tests/libsvn_wc/op-depth-test.c
  (check_tree_conflict_repos_path): New helper.
  (move_update_conflicts): New test.
  (test_funcs): Add new test.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
    subversion/trunk/subversion/tests/libsvn_wc/utils.c
    subversion/trunk/subversion/tests/libsvn_wc/utils.h

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=1432233&r1=1432232&r2=1432233&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Fri Jan 11 19:06:47 2013
@@ -110,6 +110,11 @@ struct tc_editor_baton {
   svn_wc__db_t *db;
   svn_wc__db_wcroot_t *wcroot;
   const char *move_root_dst_relpath;
+
+  /* The most recent conflict raised during this drive.  We rely on the
+     non-Ev2, depth-first, drive for this to make sense. */
+  const char *conflict_root_relpath;
+
   svn_wc_conflict_version_t *old_version;
   svn_wc_conflict_version_t *new_version;
   svn_wc_notify_func2_t notify_func;
@@ -119,7 +124,6 @@ struct tc_editor_baton {
 
 static svn_error_t *
 mark_tree_conflict(struct tc_editor_baton *b,
-                   const char *conflict_root_relpath,
                    const char *local_relpath,
                    svn_node_kind_t old_kind,
                    svn_node_kind_t new_kind,
@@ -131,9 +135,11 @@ mark_tree_conflict(struct tc_editor_bato
   svn_skel_t *conflict = svn_wc__conflict_skel_create(scratch_pool);
   svn_wc_conflict_version_t *old_version, *new_version;
 
+  b->conflict_root_relpath = apr_pstrdup(b->result_pool, local_relpath);
+
   SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                      conflict, NULL,
-                     svn_dirent_join(b->wcroot->abspath, conflict_root_relpath,
+                     svn_dirent_join(b->wcroot->abspath, local_relpath,
                                      scratch_pool),
                      reason,
                      action,
@@ -171,16 +177,18 @@ mark_tree_conflict(struct tc_editor_bato
   SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict,
                                               old_version, new_version,
                                               scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, conflict_root_relpath,
+  SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, local_relpath,
                                             conflict, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
-/* If LOCAL_RELPATH is shadowed then set *IS_CONFLICTED to TRUE and
+/* If LOCAL_RELPATH is a child of the most recently raised
+   tree-conflict or is shadowed then set *IS_CONFLICTED to TRUE and
    raise a tree-conflict on the root of the obstruction if such a
    tree-conflict does not already exist.  KIND is the kind of the
-   incoming LOCAL_RELPATH. */
+   incoming LOCAL_RELPATH. This relies on the non-Ev2, depth-first,
+   drive. */
 static svn_error_t *
 check_tree_conflict(svn_boolean_t *is_conflicted,
                     struct tc_editor_baton *b,
@@ -197,6 +205,16 @@ check_tree_conflict(svn_boolean_t *is_co
   const char *moved_to_relpath;
   svn_skel_t *conflict;
 
+  if (b->conflict_root_relpath)
+    {
+      if (svn_relpath_skip_ancestor(b->conflict_root_relpath, local_relpath))
+        {
+          *is_conflicted = TRUE;
+          return SVN_NO_ERROR;
+        }
+      b->conflict_root_relpath = NULL;
+    }
+
   SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
                                     STMT_SELECT_LOWEST_WORKING_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, local_relpath,
@@ -219,8 +237,11 @@ check_tree_conflict(svn_boolean_t *is_co
   *is_conflicted = TRUE;
 
   while (relpath_depth(conflict_root_relpath) > op_depth)
-    conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
-                                                scratch_pool);
+    {
+      conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
+                                                  scratch_pool);
+      old_kind = svn_node_dir;
+    }
 
   SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, b->wcroot,
                                             conflict_root_relpath,
@@ -235,14 +256,12 @@ check_tree_conflict(svn_boolean_t *is_co
                                             b->wcroot, conflict_root_relpath,
                                             scratch_pool, scratch_pool));
 
-  SVN_ERR(mark_tree_conflict(b, conflict_root_relpath, local_relpath,
-                             old_kind, kind,
+  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),
                              svn_wc_conflict_action_edit,
                              scratch_pool));
-
   return SVN_NO_ERROR;
 }
 
@@ -280,7 +299,7 @@ tc_editor_add_directory(void *baton,
     {
     case svn_node_file:
     default:
-      SVN_ERR(mark_tree_conflict(b, relpath, relpath, kind, svn_node_dir,
+      SVN_ERR(mark_tree_conflict(b, relpath, kind, svn_node_dir,
                                  svn_wc_conflict_reason_unversioned,
                                  svn_wc_conflict_action_add,
                                  scratch_pool));
@@ -333,7 +352,7 @@ tc_editor_add_file(void *baton,
 
   if (kind != svn_node_none)
     {
-      SVN_ERR(mark_tree_conflict(b, relpath, relpath, kind, svn_node_file,
+      SVN_ERR(mark_tree_conflict(b, relpath, kind, svn_node_file,
                                  svn_wc_conflict_reason_unversioned,
                                  svn_wc_conflict_action_add,
                                  scratch_pool));
@@ -731,8 +750,6 @@ tc_editor_alter_file(void *baton,
   new_version.checksum = new_checksum ? new_checksum : old_version.checksum;
   new_version.props = new_props ? new_props : old_version.props;
 
-  /* ### TODO update revision etc. in NODES table */
-
   /* Update file and prop contents if the update has changed them. */
   if (!svn_checksum_match(new_checksum, old_version.checksum)
       /* ### || props have changed */)
@@ -1017,6 +1034,8 @@ update_moved_away_dir(svn_editor_t *tc_e
   SVN_ERR(svn_wc__db_read_pristine_props(&new_props, db, src_abspath,
                                          scratch_pool, scratch_pool));
 
+  /* This is a non-Ev2, depth-first, drive that calls add/alter on all
+     directories. */
   if (add)
     SVN_ERR(svn_editor_add_directory(tc_editor, dst_relpath,
                                      new_children, new_props,
@@ -1121,7 +1140,6 @@ update_moved_away_subtree(svn_editor_t *
       svn_pool_clear(iterpool);
       child_dst_relpath = svn_relpath_join(dst_relpath, dst_name, iterpool);
 
-      /* FIXME: editor API violation: missing svn_editor_alter_directory. */
       SVN_ERR(svn_editor_delete(tc_editor, child_dst_relpath,
                                 move_root_dst_revision));
     }

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=1432233&r1=1432232&r2=1432233&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Fri Jan 11 19:06:47 2013
@@ -5493,6 +5493,144 @@ nested_move_update2(const svn_test_opts_
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+check_tree_conflict_repos_path(svn_test__sandbox_t *b,
+                               const char *wc_path,
+                               const char *repos_path1,
+                               const char *repos_path2)
+{
+  svn_skel_t *conflict;
+  SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db,
+                                   sbox_wc_path(b, wc_path),
+                                   b->pool, b->pool));
+  SVN_ERR_ASSERT(conflict->children);
+  conflict = conflict->children;
+  SVN_ERR_ASSERT(conflict->children);
+  conflict = conflict->children;
+  SVN_ERR_ASSERT(conflict->next);
+  conflict = conflict->next;
+  SVN_ERR_ASSERT(conflict->children);
+  conflict = conflict->children;
+  if (repos_path1)
+    {
+      svn_skel_t *conflict2 = conflict;
+
+      SVN_ERR_ASSERT(conflict2->children);
+      conflict2 = conflict2->children;
+      SVN_ERR_ASSERT(conflict2->next);
+      conflict2 = conflict2->next;
+      SVN_ERR_ASSERT(conflict2->next);
+      conflict2 = conflict2->next;
+      SVN_ERR_ASSERT(conflict2->next);
+      conflict2 = conflict2->next;
+      SVN_ERR_ASSERT(!strncmp(conflict2->data, repos_path1, conflict2->len));
+    }
+  SVN_ERR_ASSERT(conflict->next);
+  conflict = conflict->next;
+  if (repos_path2)
+    {
+      svn_skel_t *conflict2 = conflict;
+
+      SVN_ERR_ASSERT(conflict2->children);
+      conflict2 = conflict2->children;
+      SVN_ERR_ASSERT(conflict2->next);
+      conflict2 = conflict2->next;
+      SVN_ERR_ASSERT(conflict2->next);
+      conflict2 = conflict2->next;
+      SVN_ERR_ASSERT(conflict2->next);
+      conflict2 = conflict2->next;
+      SVN_ERR_ASSERT(!strncmp(conflict2->data, repos_path2, conflict2->len));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move_update_conflicts(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_update_conflicts", opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "X"));
+  SVN_ERR(sbox_wc_mkdir(&b, "X/A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "X/A/B"));
+  SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C"));
+  SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C/D"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/C/D/E"));
+  SVN_ERR(sbox_wc_mkdir(&b, "X/A/B/F"));
+  SVN_ERR(sbox_wc_commit(&b, ""));
+  SVN_ERR(sbox_wc_switch(&b, "/X"));
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+  SVN_ERR(sbox_wc_move(&b, "A2/B/C", "A2/B/C2"));
+  sbox_file_write(&b, "A2/B/F", "obstruction\n");
+
+  {
+    nodes_row_t nodes[] = {
+      {0, "",          "normal",       1, "X"},
+      {0, "A",         "normal",       1, "X/A"},
+      {0, "A/B",       "normal",       1, "X/A/B"},
+      {0, "A/B/C",     "normal",       1, "X/A/B/C"},
+      {0, "A/B/C/D",   "normal",       1, "X/A/B/C/D"},
+      {1, "A",         "base-deleted", NO_COPY_FROM, "A2"},
+      {1, "A/B",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C/D",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",        "normal",       1, "X/A", MOVED_HERE},
+      {1, "A2/B",      "normal",       1, "X/A/B", MOVED_HERE},
+      {1, "A2/B/C",    "normal",       1, "X/A/B/C", MOVED_HERE},
+      {1, "A2/B/C/D",  "normal",       1, "X/A/B/C/D", MOVED_HERE},
+      {3, "A2/B/C",    "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+      {3, "A2/B/C/D",  "base-deleted", NO_COPY_FROM},
+      {3, "A2/B/C2",   "normal",       1, "X/A/B/C", MOVED_HERE},
+      {3, "A2/B/C2/D", "normal",       1, "X/A/B/C/D", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_update(&b, "A", 2));
+  SVN_ERR(check_tree_conflict_repos_path(&b, "A", "X/A", "X/A"));
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_wc_conflict_choose_mine_conflict));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",           "normal",       1, "X"},
+      {0, "A",          "normal",       2, "X/A"},
+      {0, "A/B",        "normal",       2, "X/A/B"},
+      {0, "A/B/C",      "normal",       2, "X/A/B/C"},
+      {0, "A/B/C/D",    "normal",       2, "X/A/B/C/D"},
+      {0, "A/B/C/D/E",  "normal",       2, "X/A/B/C/D/E"},
+      {0, "A/B/F",      "normal",       2, "X/A/B/F"},
+      {1, "A",          "base-deleted", NO_COPY_FROM, "A2"},
+      {1, "A/B",        "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",      "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C/D",    "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C/D/E",  "base-deleted", NO_COPY_FROM},
+      {1, "A/B/F",      "base-deleted", NO_COPY_FROM},
+      {1, "A2",         "normal",       2, "X/A", MOVED_HERE},
+      {1, "A2/B",       "normal",       2, "X/A/B", MOVED_HERE},
+      {1, "A2/B/C",     "normal",       2, "X/A/B/C", MOVED_HERE},
+      {1, "A2/B/C/D",   "normal",       2, "X/A/B/C/D", MOVED_HERE},
+      {1, "A2/B/C/D/E", "normal",       2, "X/A/B/C/D/E", MOVED_HERE},
+      {1, "A2/B/F",     "normal",       2, "X/A/B/F", MOVED_HERE},
+      {3, "A2/B/C",     "base-deleted", NO_COPY_FROM, "A2/B/C2"},
+      {3, "A2/B/C/D",   "base-deleted", NO_COPY_FROM},
+      {3, "A2/B/C/D/E", "base-deleted", NO_COPY_FROM},
+      {3, "A2/B/C2",    "normal",       1, "X/A/B/C", MOVED_HERE},
+      {3, "A2/B/C2/D",  "normal",       1, "X/A/B/C/D", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(check_tree_conflict_repos_path(&b, "A2/B/C", "X/A/B/C", "X/A/B/C"));
+  SVN_ERR(check_tree_conflict_repos_path(&b, "A2/B/F", NULL, "X/A/B/F"));
+
+  return SVN_NO_ERROR;
+}
+
 
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
@@ -5598,5 +5736,7 @@ struct svn_test_descriptor_t test_funcs[
                        "nested_move_commit"),
     SVN_TEST_OPTS_PASS(nested_move_update2,
                        "nested_move_update2"),
+    SVN_TEST_OPTS_PASS(move_update_conflicts,
+                       "move_update_conflicts"),
     SVN_TEST_NULL
   };

Modified: subversion/trunk/subversion/tests/libsvn_wc/utils.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/utils.c?rev=1432233&r1=1432232&r2=1432233&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/utils.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/utils.c Fri Jan 11 19:06:47 2013
@@ -334,6 +334,25 @@ sbox_wc_update(svn_test__sandbox_t *b, c
 }
 
 svn_error_t *
+sbox_wc_switch(svn_test__sandbox_t *b, const char *url)
+{
+  svn_client_ctx_t *ctx;
+  svn_revnum_t result_rev;
+  svn_opt_revision_t head_rev = { svn_opt_revision_head, {0} };
+
+  url = apr_pstrcat(b->pool, b->repos_url, url, (char*)NULL);
+  SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool));
+  ctx->wc_ctx = b->wc_ctx;
+  return svn_client_switch3(&result_rev, sbox_wc_path(b, ""), url,
+                            &head_rev, &head_rev, svn_depth_infinity,
+                            FALSE /* depth_is_sticky */,
+                            TRUE /* ignore_externals */,
+                            FALSE /* allow_unver_obstructions */,
+                            TRUE /* ignore_ancestry */,
+                            ctx, b->pool);
+}
+
+svn_error_t *
 sbox_wc_resolved(svn_test__sandbox_t *b, const char *path)
 {
   return sbox_wc_resolve(b, path, svn_wc_conflict_choose_merged);

Modified: subversion/trunk/subversion/tests/libsvn_wc/utils.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/utils.h?rev=1432233&r1=1432232&r2=1432233&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/utils.h (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/utils.h Fri Jan 11 19:06:47 2013
@@ -130,6 +130,9 @@ sbox_wc_commit_ex(svn_test__sandbox_t *b
 svn_error_t *
 sbox_wc_update(svn_test__sandbox_t *b, const char *path, svn_revnum_t revnum);
 
+svn_error_t *
+sbox_wc_switch(svn_test__sandbox_t *b, const char *url);
+
 /* */
 svn_error_t *
 sbox_wc_resolved(svn_test__sandbox_t *b, const char *path);