You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2012/12/08 02:13:44 UTC
svn commit: r1418585 - in /subversion/trunk/subversion:
libsvn_wc/wc_db_update_move.c tests/libsvn_wc/op-depth-test.c
Author: julianfoad
Date: Sat Dec 8 01:13:44 2012
New Revision: 1418585
URL: http://svn.apache.org/viewvc?rev=1418585&view=rev
Log:
Teach the update-move code to handle the props of a locally moved file,
where until now it was only handling the text. Add a test for this.
* subversion/libsvn_wc/wc_db_update_move.c
(file_version_t): Add a 'props' member.
(update_working_file): Handle the props as well. Process the conflict
'skel' in common for both the text and the props.
(tc_editor_alter_file, update_moved_away_file): Get and pass on the props.
* subversion/tests/libsvn_wc/op-depth-test.c
(NOT_MOVED): New macro.
(update_prop_mod_into_moved): New test.
(test_funcs): Add it.
Modified:
subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
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=1418585&r1=1418584&r2=1418585&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Sat Dec 8 01:13:44 2012
@@ -39,6 +39,7 @@
#include "svn_editor.h"
#include "svn_error.h"
#include "svn_wc.h"
+#include "svn_props.h"
#include "svn_pools.h"
#include "private/svn_skel.h"
@@ -46,6 +47,7 @@
#include "private/svn_wc_private.h"
#include "wc.h"
+#include "props.h"
#include "wc_db_private.h"
#include "wc-queries.h"
#include "conflicts.h"
@@ -177,6 +179,7 @@ check_shadowed_node(svn_boolean_t *is_sh
typedef struct file_version_t
{
svn_wc_conflict_version_t *location_and_kind;
+ apr_hash_t *props;
const svn_checksum_t *checksum;
} file_version_t;
@@ -213,8 +216,36 @@ update_working_file(svn_skel_t **work_it
const char *old_pristine_abspath;
const char *new_pristine_abspath;
svn_skel_t *conflict_skel = NULL;
+ apr_hash_t *actual_props, *new_actual_props;
+ apr_array_header_t *propchanges;
enum svn_wc_merge_outcome_t merge_outcome;
- svn_wc_notify_state_t content_state;
+ svn_wc_notify_state_t prop_state, content_state;
+
+ /*
+ * Run a 3-way prop merge to update the props, using the pre-update
+ * props as the merge base, the post-update props as the
+ * merge-left version, and the current props of the
+ * moved-here working file as the merge-right version.
+ */
+ SVN_ERR(svn_wc__db_read_props(&actual_props,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_prop_diffs(&propchanges,
+ new_version->props, old_version->props,
+ scratch_pool));
+ SVN_ERR(svn_wc__merge_props(&conflict_skel, &prop_state,
+ NULL, &new_actual_props,
+ db, local_abspath,
+ old_version->props, old_version->props,
+ actual_props, propchanges,
+ scratch_pool, scratch_pool));
+ /* ### TODO: Make a WQ item in WORK_ITEMS to set new_actual_props ... */
+ /* ### Not a direct DB op like this... */
+ SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
+ new_actual_props,
+ svn_wc__has_magic_property(propchanges),
+ NULL/*conflict_skel*/, NULL/*work_items*/,
+ scratch_pool));
/*
* Run a 3-way merge to update the file, using the pre-update
@@ -237,36 +268,40 @@ update_working_file(svn_skel_t **work_it
local_abspath,
local_abspath,
NULL, NULL, NULL, /* diff labels */
- NULL, /* actual props */
+ actual_props,
FALSE, /* dry-run */
NULL, /* diff3-cmd */
NULL, /* merge options */
- NULL, /* prop_diff */
+ propchanges,
NULL, NULL, /* cancel_func + baton */
result_pool, scratch_pool));
- if (merge_outcome == svn_wc_merge_conflict)
+ /* If there are any conflicts to be stored, convert them into work items
+ * too. */
+ if (conflict_skel)
{
- if (conflict_skel)
- {
- svn_skel_t *work_item;
- svn_wc_conflict_version_t *original_version;
+ svn_skel_t *work_item;
+ svn_wc_conflict_version_t *original_version;
- original_version = svn_wc_conflict_version_dup(
- old_version->location_and_kind, scratch_pool);
- original_version->path_in_repos = repos_relpath;
- original_version->node_kind = svn_node_file;
- SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel,
- original_version,
- scratch_pool,
- scratch_pool));
- SVN_ERR(svn_wc__conflict_create_markers(&work_item, db,
- local_abspath,
- conflict_skel,
+ original_version = svn_wc_conflict_version_dup(
+ old_version->location_and_kind, scratch_pool);
+ original_version->path_in_repos = repos_relpath;
+ original_version->node_kind = svn_node_file;
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel,
+ original_version,
scratch_pool,
scratch_pool));
- *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
- }
+ /* According to this func's doc string, it is "Currently only used for
+ * property conflicts as text conflict markers are just in-wc files." */
+ SVN_ERR(svn_wc__conflict_create_markers(&work_item, db,
+ local_abspath,
+ conflict_skel,
+ scratch_pool,
+ scratch_pool));
+ *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+ }
+ if (merge_outcome == svn_wc_merge_conflict)
+ {
content_state = svn_wc_notify_state_conflicted;
}
else
@@ -292,7 +327,7 @@ update_working_file(svn_skel_t **work_it
scratch_pool);
notify->kind = svn_node_file;
notify->content_state = content_state;
- notify->prop_state = svn_wc_notify_state_unknown; /* ### TODO */
+ notify->prop_state = prop_state;
notify->old_revision = old_version->location_and_kind->peg_rev;
notify->revision = new_version->location_and_kind->peg_rev;
notify_func(notify_baton, notify, scratch_pool);
@@ -324,7 +359,7 @@ tc_editor_alter_file(void *baton,
SVN_ERR(svn_wc__db_depth_get_info(NULL, &move_dst_kind, &move_dst_revision,
&move_dst_repos_relpath, NULL, NULL, NULL,
NULL, NULL, &old_version.checksum, NULL,
- NULL, NULL,
+ NULL, &old_version.props,
b->wcroot, dst_relpath,
relpath_depth(b->move_root_dst_relpath),
scratch_pool, scratch_pool));
@@ -334,8 +369,9 @@ tc_editor_alter_file(void *baton,
old_version.location_and_kind = b->old_version;
new_version.location_and_kind = b->new_version;
- /* If new checksum is null that means no change. */
+ /* If new checksum is null that means no change; similarly props. */
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 */
@@ -605,11 +641,12 @@ update_moved_away_file(svn_editor_t *tc_
svn_kind_t kind;
svn_stream_t *new_contents;
const svn_checksum_t *new_checksum;
+ apr_hash_t *new_props;
/* Read post-update contents from the updated moved-away file and tell
* the editor to merge them into the moved-here file. */
SVN_ERR(svn_wc__db_read_pristine_info(NULL, &kind, NULL, NULL, NULL, NULL,
- &new_checksum, NULL, NULL, NULL,
+ &new_checksum, NULL, NULL, &new_props,
db, svn_dirent_join(wcroot->abspath,
src_relpath,
scratch_pool),
@@ -627,8 +664,7 @@ update_moved_away_file(svn_editor_t *tc_
else
SVN_ERR(svn_editor_alter_file(tc_editor, dst_relpath,
move_root_dst_revision,
- NULL, /* ### TODO props */
- new_checksum,
+ new_props, new_checksum,
new_contents));
SVN_ERR(svn_stream_close(new_contents));
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=1418585&r1=1418584&r2=1418585&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Sat Dec 8 01:13:44 2012
@@ -106,6 +106,7 @@ typedef struct nodes_row_t {
* that has no copy-from info. */
#define NO_COPY_FROM SVN_INVALID_REVNUM, NULL, FALSE
#define MOVED_HERE FALSE, NULL, TRUE
+#define NOT_MOVED FALSE, NULL, FALSE
/* Return a comma-separated list of the prop names in PROPS, in lexically
* ascending order, or NULL if PROPS is empty or NULL. (Here, we don't
@@ -4986,6 +4987,125 @@ mixed_rev_move(const svn_test_opts_t *op
return SVN_NO_ERROR;
}
+/* Test the result of 'update' when the incoming changes are inside a
+ * directory that is locally moved. */
+static svn_error_t *
+update_prop_mod_into_moved(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "update_prop_mod_into_moved", opts, pool));
+
+ /* r1: Create files 'f', 'h' */
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ sbox_file_write(&b, "A/B/f", "r1 content\n");
+ sbox_file_write(&b, "A/B/h", "r1 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/f"));
+ SVN_ERR(sbox_wc_add(&b, "A/B/h"));
+ SVN_ERR(sbox_wc_propset(&b, "pd", "f1", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pn", "f1", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pm", "f1", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "p", "h1", "A/B/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r2: Modify 'f'. Delete prop 'pd', modify prop 'pm', add prop 'pa',
+ * leave prop 'pn' unchanged. */
+ sbox_file_write(&b, "A/B/f", "r1 content\nr2 content\n");
+ SVN_ERR(sbox_wc_propset(&b, "pd", NULL, "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pm", "f2", "A/B/f"));
+ SVN_ERR(sbox_wc_propset(&b, "pa", "f2", "A/B/f"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ /* r3: Delete 'h', add 'g' */
+ sbox_file_write(&b, "A/B/g", "r3 content\n");
+ SVN_ERR(sbox_wc_add(&b, "A/B/g"));
+ SVN_ERR(sbox_wc_propset(&b, "p", "g3", "A/B/g"));
+ SVN_ERR(sbox_wc_delete(&b, "A/B/h"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/f", "normal", 1, "A/B/f", NOT_MOVED, "pd,pm,pn"},
+ {0, "A/B/h", "normal", 1, "A/B/h", NOT_MOVED, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* A is single-revision so A2 is a single-revision copy */
+ SVN_ERR(sbox_wc_move(&b, "A", "A2"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 1, "A/B"},
+ {0, "A/B/f", "normal", 1, "A/B/f", NOT_MOVED, "pd,pm,pn"},
+ {0, "A/B/h", "normal", 1, "A/B/h", NOT_MOVED, "p"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 1, "A/B/f", MOVED_HERE, "pd,pm,pn"},
+ {1, "A2/B/h", "normal", 1, "A/B/h", MOVED_HERE, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Update causes a tree-conflict on A due to incoming text-change. */
+ SVN_ERR(sbox_wc_update(&b, "", 2));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f", NOT_MOVED, "pa,pm,pn"},
+ {0, "A/B/h", "normal", 2, "A/B/h", NOT_MOVED, "p"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 1, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 1, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 1, "A/B/f", MOVED_HERE, "pd,pm,pn"},
+ {1, "A2/B/h", "normal", 1, "A/B/h", MOVED_HERE, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ /* Resolve should update the move. */
+ SVN_ERR(sbox_wc_resolve(&b, "A", svn_wc_conflict_choose_mine_conflict));
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 2, ""},
+ {0, "A", "normal", 2, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/f", "normal", 2, "A/B/f", NOT_MOVED, "pa,pm,pn"},
+ {0, "A/B/h", "normal", 2, "A/B/h", NOT_MOVED, "p"},
+ {1, "A", "base-deleted", NO_COPY_FROM, "A2"},
+ {1, "A/B", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/f", "base-deleted", NO_COPY_FROM},
+ {1, "A/B/h", "base-deleted", NO_COPY_FROM},
+ {1, "A2", "normal", 2, "A", MOVED_HERE},
+ {1, "A2/B", "normal", 2, "A/B", MOVED_HERE},
+ {1, "A2/B/f", "normal", 2, "A/B/f", MOVED_HERE, "pa,pm,pn"},
+ {1, "A2/B/h", "normal", 2, "A/B/h", MOVED_HERE, "p"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* ---------------------------------------------------------------------- */
/* The list of test functions */
@@ -5083,5 +5203,7 @@ struct svn_test_descriptor_t test_funcs[
"follow_moved_to"),
SVN_TEST_OPTS_PASS(mixed_rev_move,
"mixed_rev_move"),
+ SVN_TEST_OPTS_PASS(update_prop_mod_into_moved,
+ "update_prop_mod_into_moved"),
SVN_TEST_NULL
};