Author: svn-role
Date: Wed Nov 28 04:00:06 2018
New Revision: 1847606
URL: http://svn.apache.org/viewvc?rev=1847606&view=rev
Log:
Merge the 1.10.x-r1846299 branch:
* r1846299
Add resolver support for unversioned directories during update/switch.
Justification:
Support or unversioned files has already been backported.
We should support directories as well for consistency.
Branch:
^/subversion/branches/1.10.x-r1846299
Votes:
+1: stsp, brane, rhuijben
Modified:
subversion/branches/1.10.x/ (props changed)
subversion/branches/1.10.x/STATUS
subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c
subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c
Propchange: subversion/branches/1.10.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Nov 28 04:00:06 2018
@@ -1,6 +1,7 @@
/subversion/branches/1.10-cache-improvements:1669168-1694487
/subversion/branches/1.10.x-issue4686:1823212-1823727
/subversion/branches/1.10.x-issue4758:1834611-1842578
+/subversion/branches/1.10.x-r1846299:1846844-1847605
/subversion/branches/1.10.x-x-shelve:1827566-1827916
/subversion/branches/1.5.x-r30215:870312
/subversion/branches/1.7.x-fs-verify:1146708,1161180
@@ -102,4 +103,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1817837,1817856,1818577-1818578,1818584,1818651,1818662,1818727,1818801,1818803,1818807,1818868,1818871,1819036-1819037,1819043,1819049,1819052,1819093,1819146,1819162,1819444,1819556-1819557,1819603,1819804,1819911,1820044,1820046-1820047,1820518,1820627,1820718,1820778,1821183,1821224,1821621,1821678,1822401,1822587,1822591,1822996,1823202-1823203,1823211,1823327,1823791,1823966,1823989,1824033,1825024,1825045,1825215,1825266,1825306,1825709,1825711,1825721,1825736,1825778,1825783,1825787-1825788,1825979,1826720-1826721,1826747,1826811,1826814,1826877,1826907,1826971,1827105,1827114,1827191,1827562,1827574,1827670,1828613,1829012,1829015,1829241,1829260,1829344,1830083,1830882-1830883,1830885,1830900-1830901,1831110,1831112,1831540,1833465,1833621,1833836,1833842,1833864,1833866,1833895,1833897,1833899,1833901,1835760,1836306,1836762,1836802,1836960,1836963,1836968,1836976,1837037,1837790,1838813,1839662,1839703,1839734,1839739,1840991,1842260,1842262,1842264,184
3888,1844882,1844987,1845204,1845261,1845408,1845555,1845577,1846403,1846406,1846704
+/subversion/trunk:1817837,1817856,1818577-1818578,1818584,1818651,1818662,1818727,1818801,1818803,1818807,1818868,1818871,1819036-1819037,1819043,1819049,1819052,1819093,1819146,1819162,1819444,1819556-1819557,1819603,1819804,1819911,1820044,1820046-1820047,1820518,1820627,1820718,1820778,1821183,1821224,1821621,1821678,1822401,1822587,1822591,1822996,1823202-1823203,1823211,1823327,1823791,1823966,1823989,1824033,1825024,1825045,1825215,1825266,1825306,1825709,1825711,1825721,1825736,1825778,1825783,1825787-1825788,1825979,1826720-1826721,1826747,1826811,1826814,1826877,1826907,1826971,1827105,1827114,1827191,1827562,1827574,1827670,1828613,1829012,1829015,1829241,1829260,1829344,1830083,1830882-1830883,1830885,1830900-1830901,1831110,1831112,1831540,1833465,1833621,1833836,1833842,1833864,1833866,1833895,1833897,1833899,1833901,1835760,1836306,1836762,1836802,1836960,1836963,1836968,1836976,1837037,1837790,1838813,1839662,1839703,1839734,1839739,1840991,1842260,1842262,1842264,184
3888,1844882,1844987,1845204,1845261,1845408,1845555,1845577,1846299,1846403,1846406,1846704
Modified: subversion/branches/1.10.x/STATUS
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10.x/STATUS?rev=1847606&r1=1847605&r2=1847606&view=diff
==============================================================================
--- subversion/branches/1.10.x/STATUS (original)
+++ subversion/branches/1.10.x/STATUS Wed Nov 28 04:00:06 2018
@@ -28,16 +28,6 @@ Veto-blocked changes:
Approved changes:
=================
- * r1846299
- Add resolver support for unversioned directories during update/switch.
- Justification:
- Support or unversioned files has already been backported.
- We should support directories as well for consistency.
- Branch:
- ^/subversion/branches/1.10.x-r1846299
- Votes:
- +1: stsp, brane, rhuijben
-
* r1847181, r1847182, r1847188, r1847264
Fix issue SVN-4792: Foreign repo copy of file adding mergeinfo.
Justification:
Modified: subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c?rev=1847606&r1=1847605&r2=1847606&view=diff
==============================================================================
--- subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c (original)
+++ subversion/branches/1.10.x/subversion/libsvn_client/conflicts.c Wed Nov 28
04:00:06 2018
@@ -7705,20 +7705,46 @@ resolve_update_incoming_added_dir_merge(
const char *local_abspath;
const char *lock_abspath;
svn_error_t *err;
+ svn_wc_conflict_reason_t local_change;
local_abspath = svn_client_conflict_get_local_abspath(conflict);
+ local_change = svn_client_conflict_get_local_change(conflict);
- SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
- &lock_abspath, ctx->wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
+ if (local_change == svn_wc_conflict_reason_unversioned)
+ {
+ char *parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+ SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
+ &lock_abspath, ctx->wc_ctx, parent_abspath,
+ scratch_pool, scratch_pool));
- err = svn_wc__conflict_tree_update_local_add(ctx->wc_ctx,
- local_abspath,
- ctx->cancel_func,
- ctx->cancel_baton,
- ctx->notify_func2,
- ctx->notify_baton2,
- scratch_pool);
+ /* The update/switch operation has added the incoming versioned
+ * directory as a deleted op-depth layer. We can revert this layer
+ * to make the incoming tree appear in the working copy.
+ * This meta-data-only revert operation effecively merges the
+ * versioned and unversioned trees but leaves all unversioned files as
+ * they were. This is the best we can do; 3-way merging of unversioned
+ * files with files from the repository is impossible because there is
+ * no known merge base. No unversioned data will be lost, and any
+ * differences to files in the repository will show up in 'svn diff'. */
+ err = svn_wc_revert5(ctx->wc_ctx, local_abspath, svn_depth_infinity,
+ FALSE, NULL, TRUE, TRUE /* metadata_only */,
+ NULL, NULL, /* no cancellation */
+ ctx->notify_func2, ctx->notify_baton2,
+ scratch_pool);
+ }
+ else
+ {
+ SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
+ &lock_abspath, ctx->wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ err = svn_wc__conflict_tree_update_local_add(ctx->wc_ctx,
+ local_abspath,
+ ctx->cancel_func,
+ ctx->cancel_baton,
+ ctx->notify_func2,
+ ctx->notify_baton2,
+ scratch_pool);
+ }
err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
lock_abspath,
@@ -9539,8 +9565,9 @@ configure_option_incoming_added_dir_merg
incoming_change == svn_wc_conflict_action_add &&
(local_change == svn_wc_conflict_reason_added ||
(operation == svn_wc_operation_merge &&
- local_change == svn_wc_conflict_reason_obstructed)))
-
+ local_change == svn_wc_conflict_reason_obstructed) ||
+ (operation != svn_wc_operation_merge &&
+ local_change == svn_wc_conflict_reason_unversioned)))
{
const char *description;
const char *wcroot_abspath;
Modified:
subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c?rev=1847606&r1=1847605&r2=1847606&view=diff
==============================================================================
--- subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c
(original)
+++ subversion/branches/1.10.x/subversion/tests/libsvn_client/conflicts-test.c
Wed Nov 28 04:00:06 2018
@@ -170,6 +170,7 @@ static const char *deleted_file_name = "
static const char *deleted_dir_name = "B";
static const char *deleted_dir_child = "lambda";
static const char *new_dir_name = "newdir";
+static const char *unversioned_file_name = "unversioned.txt";
/* File property content. */
static const char *propval_trunk = "This is a property on the trunk.";
@@ -187,6 +188,8 @@ static const char *added_file_on_branch_
"This is a file added on the branch\n";
static const char *modified_file_in_working_copy_content =
"This is a modified file in the working copy\n";
+static const char *unversioned_file_content =
+ "This is an unversioned file\n";
/* A helper function which prepares a working copy for the tests below. */
static svn_error_t *
@@ -5756,6 +5759,230 @@ test_switch_file_add_vs_unversiond_file(
return SVN_NO_ERROR;
}
+static svn_error_t *
+create_unversioned_dir(const char **new_file_path,
+ const char **unversioned_file_path,
+ const char *new_dir_path,
+ svn_test__sandbox_t *b, apr_pool_t *pool)
+{
+ apr_file_t *file;
+ apr_size_t content_len;
+
+ /* Create an unversioned directory. */
+ SVN_ERR(svn_io_dir_make(sbox_wc_path(b, new_dir_path), APR_OS_DEFAULT,
+ b->pool));
+
+ /* Create an unversioned file which will collide with a versioned file. */
+ *new_file_path = svn_relpath_join(new_dir_path, new_file_name, b->pool);
+ SVN_ERR(svn_io_file_open(&file, sbox_wc_path(b, *new_file_path),
+ (APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE), APR_OS_DEFAULT,
+ b->pool));
+ content_len = strlen(unversioned_file_content);
+ SVN_ERR(svn_io_file_write(file, unversioned_file_content, &content_len,
+ b->pool));
+ SVN_ERR(svn_io_file_close(file, b->pool));
+
+ /* Create another unversioned file at a different path. */
+ *unversioned_file_path = svn_relpath_join(new_dir_path,
unversioned_file_name,
+ b->pool);
+ SVN_ERR(svn_io_file_open(&file, sbox_wc_path(b, *unversioned_file_path),
+ (APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE), APR_OS_DEFAULT,
+ b->pool));
+ content_len = strlen(unversioned_file_content);
+ SVN_ERR(svn_io_file_write(file, unversioned_file_content, &content_len,
+ b->pool));
+ SVN_ERR(svn_io_file_close(file, b->pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+resolve_added_dir_vs_unversioned_dir(const char *new_dir_path,
+ const char *new_file_path,
+ const char *unversioned_file_path,
+ svn_test__sandbox_t *b, apr_pool_t *pool)
+{
+ svn_client_ctx_t *ctx;
+ svn_client_conflict_t *conflict;
+ svn_opt_revision_t opt_rev;
+ struct status_baton sb;
+ struct svn_client_status_t *status;
+ svn_stringbuf_t *buf;
+
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+ SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, new_dir_path),
+ ctx, b->pool, b->pool));
+ SVN_TEST_ASSERT(svn_client_conflict_get_local_change(conflict) ==
+ svn_wc_conflict_reason_unversioned);
+ SVN_TEST_ASSERT(svn_client_conflict_get_incoming_change(conflict) ==
+ svn_wc_conflict_action_add);
+ {
+ 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_added_dir_merge,
+ -1 /* end of list */
+ };
+ SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts,
+ b->pool));
+ }
+
+ SVN_ERR(svn_client_conflict_tree_resolve_by_id(
+ conflict,
+ svn_client_conflict_option_incoming_added_dir_merge,
+ ctx, b->pool));
+
+ /* Ensure that the directory has the expected status. */
+ opt_rev.kind = svn_opt_revision_working;
+ sb.result_pool = b->pool;
+ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_dir_path),
+ &opt_rev, svn_depth_unknown, TRUE, TRUE,
+ TRUE, TRUE, FALSE, TRUE, NULL,
+ status_func, &sb, b->pool));
+ status = sb.status;
+ SVN_TEST_ASSERT(status->kind == svn_node_dir);
+ SVN_TEST_ASSERT(status->versioned);
+ SVN_TEST_ASSERT(!status->conflicted);
+ SVN_TEST_ASSERT(status->node_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_normal);
+ SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+ SVN_TEST_ASSERT(!status->copied);
+ SVN_TEST_ASSERT(!status->switched);
+ SVN_TEST_ASSERT(!status->file_external);
+ SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+ SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+ /* Ensure that the "collision" file has the expected status. */
+ opt_rev.kind = svn_opt_revision_working;
+ sb.result_pool = b->pool;
+ SVN_ERR(svn_client_status6(NULL, ctx, sbox_wc_path(b, new_file_path),
+ &opt_rev, svn_depth_unknown, TRUE, TRUE,
+ TRUE, TRUE, FALSE, TRUE, NULL,
+ status_func, &sb, b->pool));
+ status = sb.status;
+ SVN_TEST_ASSERT(status->kind == svn_node_file);
+ SVN_TEST_ASSERT(status->versioned);
+ SVN_TEST_ASSERT(!status->conflicted);
+ SVN_TEST_ASSERT(status->node_status == svn_wc_status_modified);
+ SVN_TEST_ASSERT(status->text_status == svn_wc_status_modified);
+ SVN_TEST_ASSERT(status->prop_status == svn_wc_status_none);
+ SVN_TEST_ASSERT(!status->copied);
+ SVN_TEST_ASSERT(!status->switched);
+ SVN_TEST_ASSERT(!status->file_external);
+ SVN_TEST_ASSERT(status->moved_from_abspath == NULL);
+ SVN_TEST_ASSERT(status->moved_to_abspath == NULL);
+
+ /* Ensure that the file has the expected content. */
+ SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, new_file_path),
+ b->pool));
+ SVN_TEST_STRING_ASSERT(buf->data, unversioned_file_content);
+
+ /* Ensure that the unversioned file has the expected status. */
+ opt_rev.kind = svn_opt_revision_working;
+ sb.result_pool = b->pool;
+ SVN_TEST_ASSERT_ERROR(
+ svn_client_status6(NULL, ctx, sbox_wc_path(b, unversioned_file_path),
+ &opt_rev, svn_depth_unknown, TRUE, TRUE,
+ TRUE, TRUE, FALSE, TRUE, NULL,
+ status_func, &sb, b->pool),
+ SVN_ERR_ENTRY_NOT_FOUND);
+
+ /* Ensure that the file has the expected content. */
+ SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b,
unversioned_file_path),
+ b->pool));
+ SVN_TEST_STRING_ASSERT(buf->data, unversioned_file_content);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_update_dir_add_vs_unversioned_dir(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b));
+ const char *new_dir_path;
+ const char *new_file_path;
+ const char *unversioned_file_path;
+
+ SVN_ERR(svn_test__sandbox_create(b, "update_dir_add_vs_unversioned_dir",
+ opts, pool));
+
+ SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+
+ /* Add a new directory */
+ new_dir_path = svn_relpath_join(trunk_path, new_dir_name, b->pool);
+ SVN_ERR(sbox_wc_mkdir(b, new_dir_path));
+ new_file_path = svn_relpath_join(new_dir_path, new_file_name, b->pool);
+ SVN_ERR(sbox_file_write(b, new_file_path, new_file_content));
+ SVN_ERR(sbox_wc_add(b, new_file_path));
+ SVN_ERR(sbox_wc_commit(b, "")); /* r2 */
+
+ SVN_ERR(sbox_wc_update(b, "", 1)); /* back to r1 */
+
+ new_dir_path = svn_relpath_join(trunk_path, new_dir_name, b->pool);
+ SVN_ERR(create_unversioned_dir(&new_file_path, &unversioned_file_path,
+ new_dir_path, b, b->pool));
+
+ SVN_ERR(sbox_wc_update(b, "", 2)); /* back to r2 */
+
+ SVN_ERR(resolve_added_dir_vs_unversioned_dir(new_dir_path, new_file_path,
+ unversioned_file_path,
+ b, b->pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_switch_dir_add_vs_unversioned_dir(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_revnum_t result_rev;
+ const char *trunk_url;
+ const char *new_dir_path;
+ const char *new_file_path;
+ const char *unversioned_file_path;
+
+ SVN_ERR(svn_test__sandbox_create(b, "switch_dir_add_vs_unversioned_dir",
+ opts, pool));
+
+ SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */
+
+ /* Create a branch of node "A". */
+ SVN_ERR(sbox_wc_copy(b, trunk_path, branch_path));
+ SVN_ERR(sbox_wc_commit(b, "")); /* r2 */
+
+ /* Add a new directory on trunk. */
+ new_dir_path = svn_relpath_join(trunk_path, new_dir_name, b->pool);
+ SVN_ERR(sbox_wc_mkdir(b, new_dir_path));
+ new_file_path = svn_relpath_join(new_dir_path, new_file_name, b->pool);
+ SVN_ERR(sbox_file_write(b, new_file_path, new_file_content));
+ SVN_ERR(sbox_wc_add(b, new_file_path));
+ SVN_ERR(sbox_wc_commit(b, "")); /* r3 */
+
+ SVN_ERR(sbox_wc_update(b, "", 2)); /* back to r2 */
+
+ new_dir_path = svn_relpath_join(branch_path, new_dir_name, b->pool);
+ SVN_ERR(create_unversioned_dir(&new_file_path, &unversioned_file_path,
+ new_dir_path, b, b->pool));
+
+ /* Switch branch to trunk. */
+ trunk_url = apr_pstrcat(b->pool, b->repos_url, "/", trunk_path, SVN_VA_NULL);
+ SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool));
+ opt_rev.kind = svn_opt_revision_head;
+ opt_rev.value.number = SVN_INVALID_REVNUM;
+ SVN_ERR(svn_client_switch3(&result_rev, sbox_wc_path(b, branch_path),
+ trunk_url, &opt_rev, &opt_rev,
+ svn_depth_infinity,
+ TRUE, FALSE, FALSE, FALSE, ctx, b->pool));
+
+ SVN_ERR(resolve_added_dir_vs_unversioned_dir(new_dir_path, new_file_path,
+ unversioned_file_path,
+ b, b->pool));
+
+ return SVN_NO_ERROR;
+}
/* ==========================================================================
*/
@@ -5856,6 +6083,10 @@ static struct svn_test_descriptor_t test
"file add vs unversioned file during update"),
SVN_TEST_OPTS_PASS(test_switch_file_add_vs_unversiond_file,
"file add vs unversioned file during switch"),
+ SVN_TEST_OPTS_PASS(test_update_dir_add_vs_unversioned_dir,
+ "dir add vs unversioned dir during update"),
+ SVN_TEST_OPTS_PASS(test_switch_dir_add_vs_unversioned_dir,
+ "dir add vs unversioned dir during switch"),
SVN_TEST_NULL
};