You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ko...@apache.org on 2016/10/18 14:57:54 UTC

svn commit: r1765452 - in /subversion/trunk/subversion: libsvn_client/conflicts.c tests/libsvn_client/conflicts-test.c

Author: kotkov
Date: Tue Oct 18 14:57:54 2016
New Revision: 1765452

URL: http://svn.apache.org/viewvc?rev=1765452&view=rev
Log:
Add a couple of failing tests for "remote move vs local edit" tree conflict
resolution upon merge.

These tests exploit a few problems in how we merge the file properties
and files with keywords.  For now, I noted them in the implementation of
the corresponding resolution option.

* subversion/libsvn_client/conflicts.c
  (resolve_incoming_move_file_text_merge): Add a comment about what needs
   to be fixed.

* subversion/tests/libsvn_client/conflicts-test.c
  (): Include "svn_props.h".
  (test_merge_incoming_move_file_prop_merge_conflict,
   test_merge_incoming_move_file_text_merge_keywords): New failing tests.
  (test_funcs): Reference new tests.

Modified:
    subversion/trunk/subversion/libsvn_client/conflicts.c
    subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c

Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1765452&r1=1765451&r2=1765452&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Tue Oct 18 14:57:54 2016
@@ -6835,7 +6835,16 @@ resolve_incoming_move_file_text_merge(sv
   if (err)
     goto unlock_wc;
 
-  /* Perform the file merge. */
+  /* Perform the file merge.
+   *
+   *  ### Need to fix what we pass as "right_abspath" here, as svn_wc_merge5()
+   *  ### expects to see the fulltext in repository-normal form (linefeeds,
+   *  ### with keywords contracted).
+   *
+   *  ### And I think we also need to patch up what we pass as original_props,
+   *  ### so that conflicting properties would actually produce a conflict.
+   *  ### See what resolve_local_move_file_merge() does.
+   */
   err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
                       ctx->wc_ctx, ancestor_abspath,
                       local_abspath, moved_to_abspath,

Modified: subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c?rev=1765452&r1=1765451&r2=1765452&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c Tue Oct 18 14:57:54 2016
@@ -28,6 +28,7 @@
 #include "svn_client.h"
 #include "svn_dirent_uri.h"
 #include "svn_hash.h"
+#include "svn_props.h"
 
 #include "../svn_test.h"
 #include "../svn_test_fs.h"
@@ -3463,6 +3464,249 @@ test_update_incoming_added_file_text_mer
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_merge_incoming_move_file_prop_merge_conflict(const svn_test_opts_t *opts,
+                                                  apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  svn_opt_revision_t opt_rev;
+  svn_client_conflict_t *conflict;
+  svn_boolean_t text_conflicted;
+  apr_array_header_t *props_conflicted;
+  svn_boolean_t tree_conflicted;
+  const svn_string_t *base_propval;
+  const svn_string_t *working_propval;
+  const svn_string_t *incoming_old_propval;
+  const svn_string_t *incoming_new_propval;
+
+  SVN_ERR(svn_test__sandbox_create(
+            b, "merge_incoming_move_file_prop_merge_conflict", opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b));
+  /* Add a file property. */
+  SVN_ERR(sbox_wc_propset(b, "prop", "val-initial", "A/mu"));;
+  SVN_ERR(sbox_wc_commit(b, ""));
+  /* Create a copy of node "A". */
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+  SVN_ERR(sbox_wc_copy(b, "A", "A1"));
+  SVN_ERR(sbox_wc_commit(b, ""));
+  /* On "trunk", move the file and edit the property. */
+  SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved"));
+  SVN_ERR(sbox_wc_propset(b, "prop", "val-trunk", "A/mu-moved"));;
+  SVN_ERR(sbox_wc_commit(b, ""));
+  /* On "branch", edit the same property. */
+  SVN_ERR(sbox_wc_propset(b, "prop", "val-branch", "A1/mu"));;
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+  opt_rev.kind = svn_opt_revision_head;
+  opt_rev.value.number = SVN_INVALID_REVNUM;
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, pool));
+
+  /* Merge "A" to "A1". */
+  SVN_ERR(svn_client_merge_peg5(svn_path_url_add_component2(b->repos_url, "A",
+                                                            pool),
+                                NULL, &opt_rev, sbox_wc_path(b, "A1"),
+                                svn_depth_infinity,
+                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+                                NULL, ctx, pool));
+
+  /* We should have a tree conflict in the file "mu". */
+  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu"), ctx,
+                                  pool, pool));
+  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
+                                             &props_conflicted,
+                                             &tree_conflicted,
+                                             conflict, pool, pool));
+  SVN_TEST_ASSERT(!text_conflicted);
+  SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0);
+  SVN_TEST_ASSERT(tree_conflicted);
+
+  /* Check available tree conflict resolution options. */
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_incoming_delete_ignore,
+      svn_client_conflict_option_incoming_delete_accept,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool));
+  }
+
+  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, pool));
+
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_incoming_move_file_text_merge,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool));
+  }
+
+  /* Resolve the tree conflict by moving "mu" to "mu-moved". */
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict, svn_client_conflict_option_incoming_move_file_text_merge,
+            ctx, pool));
+
+  /* We should now have a property conflict in the file "mu-moved".
+   *
+   * XFAIL: Currently, there is no property conflict.
+   */
+  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"),
+                                  ctx, pool, pool));
+  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
+                                             &props_conflicted,
+                                             &tree_conflicted,
+                                             conflict, pool, pool));
+  SVN_TEST_ASSERT(!text_conflicted);
+  SVN_TEST_INT_ASSERT(props_conflicted->nelts, 1);
+  SVN_TEST_STRING_ASSERT(APR_ARRAY_IDX(props_conflicted, 0, const char *),
+                         "prop");
+  SVN_TEST_ASSERT(!tree_conflicted);
+
+  /* Check available property conflict resolution options. */
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_base_text,
+      svn_client_conflict_option_incoming_text,
+      svn_client_conflict_option_working_text,
+      svn_client_conflict_option_incoming_text_where_conflicted,
+      svn_client_conflict_option_working_text_where_conflicted,
+      svn_client_conflict_option_merged_text,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_prop_conflict_options(conflict, ctx, expected_opts, pool));
+  }
+
+  /* Check conflicted property values. */
+  SVN_ERR(svn_client_conflict_prop_get_propvals(&base_propval,
+                                                &working_propval,
+                                                &incoming_old_propval,
+                                                &incoming_new_propval,
+                                                conflict, "prop", pool));
+  /* ### Is this the proper expectation for base_propval? */
+  SVN_TEST_STRING_ASSERT(base_propval->data, "val-branch");
+  SVN_TEST_STRING_ASSERT(working_propval->data, "val-branch");
+  SVN_TEST_STRING_ASSERT(incoming_old_propval->data, "val-initial");
+  SVN_TEST_STRING_ASSERT(incoming_new_propval->data, "val-trunk");
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_merge_incoming_move_file_text_merge_keywords(const svn_test_opts_t *opts,
+                                                  apr_pool_t *pool)
+{
+  svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+  svn_client_ctx_t *ctx;
+  svn_opt_revision_t opt_rev;
+  svn_client_conflict_t *conflict;
+  svn_boolean_t text_conflicted;
+  apr_array_header_t *props_conflicted;
+  svn_boolean_t tree_conflicted;
+  svn_stringbuf_t *buf;
+
+  SVN_ERR(svn_test__sandbox_create(
+            b, "merge_incoming_move_file_text_merge_keywords", opts, pool));
+
+  SVN_ERR(sbox_add_and_commit_greek_tree(b));
+  /* Set svn:keywords on a file. */
+  SVN_ERR(sbox_wc_propset(b, SVN_PROP_KEYWORDS, "Revision", "A/mu"));;
+  SVN_ERR(sbox_wc_commit(b, ""));
+  /* Create a copy of node "A". */
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+  SVN_ERR(sbox_wc_copy(b, "A", "A1"));
+  SVN_ERR(sbox_wc_commit(b, ""));
+  /* On "trunk", begin using keywords in the file and move it. */
+  SVN_ERR(sbox_file_write(b, "A/mu", "$Revision$\n"));
+  SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved"));
+  SVN_ERR(sbox_wc_commit(b, ""));
+  /* On "branch", edit the file and make it equal to what's in trunk. */
+  SVN_ERR(sbox_file_write(b, "A1/mu", "$Revision$\n"));
+  SVN_ERR(sbox_wc_commit(b, ""));
+
+  SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM));
+  opt_rev.kind = svn_opt_revision_head;
+  opt_rev.value.number = SVN_INVALID_REVNUM;
+  SVN_ERR(svn_test__create_client_ctx(&ctx, b, pool));
+
+  /* Merge "A" to "A1". */
+  SVN_ERR(svn_client_merge_peg5(svn_path_url_add_component2(b->repos_url, "A",
+                                                            pool),
+                                NULL, &opt_rev, sbox_wc_path(b, "A1"),
+                                svn_depth_infinity,
+                                FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+                                NULL, ctx, pool));
+
+  /* We should have a tree conflict in the file "mu". */
+  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu"), ctx,
+                                  pool, pool));
+  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
+                                             &props_conflicted,
+                                             &tree_conflicted,
+                                             conflict, pool, pool));
+  SVN_TEST_ASSERT(!text_conflicted);
+  SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0);
+  SVN_TEST_ASSERT(tree_conflicted);
+
+  /* Check available tree conflict resolution options. */
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_incoming_delete_ignore,
+      svn_client_conflict_option_incoming_delete_accept,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool));
+  }
+
+  SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, pool));
+
+  {
+    svn_client_conflict_option_id_t expected_opts[] = {
+      svn_client_conflict_option_postpone,
+      svn_client_conflict_option_accept_current_wc_state,
+      svn_client_conflict_option_incoming_move_file_text_merge,
+      -1 /* end of list */
+    };
+    SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool));
+  }
+
+  /* Resolve the tree conflict by moving "mu" to "mu-moved". */
+  SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+            conflict, svn_client_conflict_option_incoming_move_file_text_merge,
+            ctx, pool));
+
+  /* The file should no longer be in conflict, and should not have a
+   * text conflict, because the contents are identical in "trunk" and
+   * in the "branch".
+   *
+   * XFAIL: Currently, there is an unexpected text conflict.
+   */
+  SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"),
+                                  ctx, pool, pool));
+  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted,
+                                             &props_conflicted,
+                                             &tree_conflicted,
+                                             conflict, pool, pool));
+  SVN_TEST_ASSERT(!text_conflicted);
+  SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0);
+  SVN_TEST_ASSERT(!tree_conflicted);
+
+  /* And it should have expected contents (with expanded keywords). */
+  SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A1/mu-moved"),
+                                   pool));
+  SVN_TEST_STRING_ASSERT(buf->data, "$Revision: 4 $\n");
+
+  return SVN_NO_ERROR;
+}
+
 /* ========================================================================== */
 
 
@@ -3523,6 +3767,10 @@ static struct svn_test_descriptor_t test
                        "update incoming dir move with nested file move"),
     SVN_TEST_OPTS_XFAIL(test_update_incoming_added_file_text_merge,
                        "update incoming add file text merge"),
+    SVN_TEST_OPTS_XFAIL(test_merge_incoming_move_file_prop_merge_conflict,
+                        "merge incoming move file merge with prop conflict"),
+    SVN_TEST_OPTS_XFAIL(test_merge_incoming_move_file_text_merge_keywords,
+                        "merge incoming move file merge with keywords"),
     SVN_TEST_NULL
   };