You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/11/28 13:03:49 UTC
svn commit: r1771732 - in /subversion/trunk/subversion:
libsvn_client/conflicts.c tests/libsvn_client/conflicts-test.c
Author: stsp
Date: Mon Nov 28 13:03:48 2016
New Revision: 1771732
URL: http://svn.apache.org/viewvc?rev=1771732&view=rev
Log:
Fix handling of keywords while resolving an incoming move of a file.
* subversion/libsvn_client/conflicts.c
(get_keywords): New helper based on similar code from libsvn_client/patch.c.
(resolve_incoming_move_file_text_merge): Convert the move target file to
repository-normal form while setting it aside. Fixes merging of keywords.
* subversion/tests/libsvn_client/conflicts-test.c
(test_merge_incoming_move_file_text_merge_keywords): Update a comment, and
fix the HEAD revision number expected by this test.
(test_func): Switch "move file merge with keywords" test to PASS.
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=1771732&r1=1771731&r2=1771732&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Mon Nov 28 13:03:48 2016
@@ -37,6 +37,7 @@
#include "svn_props.h"
#include "svn_hash.h"
#include "svn_sorts.h"
+#include "svn_subst.h"
#include "client.h"
#include "private/svn_diff_tree.h"
@@ -6840,6 +6841,57 @@ unlock_wc:
return SVN_NO_ERROR;
}
+/* Get KEYWORDS for LOCAL_ABSPATH.
+ * WC_CTX is a context for the working copy the patch is applied to.
+ * Use RESULT_POOL for allocations of fields in TARGET.
+ * Use SCRATCH_POOL for all other allocations. */
+static svn_error_t *
+get_keywords(apr_hash_t **keywords,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *props;
+ svn_string_t *keywords_val;
+
+ SVN_ERR(svn_wc_prop_list2(&props, wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ keywords_val = svn_hash_gets(props, SVN_PROP_KEYWORDS);
+ if (keywords_val)
+ {
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *rev_str;
+ const char *author;
+ const char *url;
+ const char *repos_root_url;
+ const char *repos_relpath;
+
+ SVN_ERR(svn_wc__node_get_changed_info(&changed_rev,
+ &changed_date,
+ &author, wc_ctx,
+ local_abspath,
+ scratch_pool,
+ scratch_pool));
+ rev_str = apr_psprintf(scratch_pool, "%ld", changed_rev);
+ SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, &repos_root_url,
+ NULL,
+ wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ url = svn_path_url_add_component2(repos_root_url, repos_relpath,
+ scratch_pool);
+
+ SVN_ERR(svn_subst_build_keywords3(keywords,
+ keywords_val->data,
+ rev_str, url, repos_root_url,
+ changed_date,
+ author, result_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_incoming_move_file_text_merge(svn_client_conflict_option_t *option,
@@ -6872,7 +6924,7 @@ resolve_incoming_move_file_text_merge(sv
struct conflict_tree_incoming_delete_details *details;
apr_array_header_t *possible_moved_to_abspaths;
const char *moved_to_abspath;
- const char *incoming_abspath;
+ const char *incoming_abspath = NULL;
local_abspath = svn_client_conflict_get_local_abspath(conflict);
operation = svn_client_conflict_get_operation(conflict);
@@ -6978,28 +7030,47 @@ resolve_incoming_move_file_text_merge(sv
}
else if (operation == svn_wc_operation_merge)
{
+ svn_stream_t *incoming_stream;
+ svn_stream_t *move_target_stream;
+ svn_stream_t *normalized_stream;
+ apr_hash_t *keywords;
+
/* Set aside the current move target file. This is required to apply
* the move, and only then perform a three-way text merge between
* the ancestor's file, our working file (which we would move to
* the destination), and the file that we have set aside, which
* contains the incoming fulltext. */
- err = svn_io_open_uniquely_named(NULL, &incoming_abspath,
- svn_dirent_dirname(moved_to_abspath,
- scratch_pool),
- svn_dirent_basename(moved_to_abspath,
- scratch_pool),
- ".tmp",
- svn_io_file_del_on_pool_cleanup,
- scratch_pool, scratch_pool);
+ err = svn_stream_open_unique(&incoming_stream,
+ &incoming_abspath, wc_tmpdir,
+ svn_io_file_del_none,
+ scratch_pool, scratch_pool);
+ if (err)
+ goto unlock_wc;
+
+ err = svn_stream_open_readonly(&move_target_stream, moved_to_abspath,
+ scratch_pool, scratch_pool);
if (err)
goto unlock_wc;
- err = svn_io_file_rename2(moved_to_abspath, incoming_abspath,
- FALSE, scratch_pool);
+ err = get_keywords(&keywords, ctx->wc_ctx, moved_to_abspath,
+ scratch_pool, scratch_pool);
+ if (err)
+ goto unlock_wc;
+
+ normalized_stream = svn_subst_stream_translated(move_target_stream,
+ "\n", TRUE,
+ keywords, FALSE,
+ scratch_pool);
+ err = svn_stream_copy3(normalized_stream, incoming_stream,
+ NULL, NULL, /* no cancellation */
+ scratch_pool);
if (err)
goto unlock_wc;
/* Apply the incoming move. */
+ err = svn_io_remove_file2(moved_to_abspath, FALSE, scratch_pool);
+ if (err)
+ goto unlock_wc;
err = svn_wc__move2(ctx->wc_ctx, local_abspath, moved_to_abspath,
FALSE, /* ordinary (not meta-data only) move */
FALSE, /* mixed-revisions don't apply to files */
@@ -7012,12 +7083,7 @@ resolve_incoming_move_file_text_merge(sv
else
SVN_ERR_MALFUNCTION();
- /* 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).
- */
+ /* Perform the file merge. */
err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
ctx->wc_ctx, ancestor_abspath,
incoming_abspath, moved_to_abspath,
@@ -7033,6 +7099,14 @@ resolve_incoming_move_file_text_merge(sv
if (err)
goto unlock_wc;
+ if (operation == svn_wc_operation_merge && incoming_abspath)
+ {
+ err = svn_io_remove_file2(incoming_abspath, TRUE, scratch_pool);
+ if (err)
+ goto unlock_wc;
+ incoming_abspath = NULL;
+ }
+
if (ctx->notify_func2)
{
svn_wc_notify_t *notify;
@@ -7074,6 +7148,11 @@ resolve_incoming_move_file_text_merge(sv
conflict->resolution_tree = option_id;
unlock_wc:
+ if (err && operation == svn_wc_operation_merge && incoming_abspath)
+ err = svn_error_quick_wrapf(
+ err, _("If needed, a backup copy of '%s' can be found at '%s'"),
+ svn_dirent_local_style(moved_to_abspath, scratch_pool),
+ svn_dirent_local_style(incoming_abspath, scratch_pool));
err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
lock_abspath,
scratch_pool));
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=1771732&r1=1771731&r2=1771732&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/conflicts-test.c Mon Nov 28 13:03:48 2016
@@ -3679,10 +3679,7 @@ test_merge_incoming_move_file_text_merge
/* 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.
- */
+ * in the "branch". */
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,
@@ -3696,7 +3693,7 @@ test_merge_incoming_move_file_text_merge
/* 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");
+ SVN_TEST_STRING_ASSERT(buf->data, "$Revision: 5 $\n");
return SVN_NO_ERROR;
}
@@ -3763,8 +3760,8 @@ static struct svn_test_descriptor_t test
"update incoming add file text merge"),
SVN_TEST_OPTS_PASS(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_OPTS_PASS(test_merge_incoming_move_file_text_merge_keywords,
+ "merge incoming move file merge with keywords"),
SVN_TEST_NULL
};