You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/07/13 18:25:40 UTC
svn commit: r1361289 - /subversion/trunk/subversion/libsvn_wc/update_editor.c
Author: rhuijben
Date: Fri Jul 13 16:25:40 2012
New Revision: 1361289
URL: http://svn.apache.org/viewvc?rev=1361289&view=rev
Log:
Consolidate the code that fills in details about conflicts in the update editor
to simplify code and avoid unneeded database accesses.
* subversion/libsvn_wc/update_editor.c
(complete_conflict): New function.
(mark_directory_edited,
mark_file_edited): Complete conflict before installing.
(create_tree_conflict): Remove function.
(check_tree_conflict): Fix typo in comment. Directly create tree conflict.
(delete_entry): Fetch data for tree conflict. Remove unused variable. Complete
conflict before installing.
(add_directory): Store conflict before clearing local variable. Create conflict
directly and complete conflict before installing.
(close_directory): Complete conflict via helper.
(add_file): Store conflict before clearing local variable. Create conflict
directly and complete conflict before installing.
(close_file): Complete conflict via helper.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1361289&r1=1361288&r2=1361289&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Fri Jul 13 16:25:40 2012
@@ -857,6 +857,56 @@ make_file_baton(struct file_baton **f_p,
return SVN_NO_ERROR;
}
+/* Complete a conflict skel by describing the update.
+ *
+ * All temporary allocations are be made in SCRATCH_POOL, while allocations
+ * needed for the returned conflict struct are made in RESULT_POOL.
+ */
+static svn_error_t *
+complete_conflict(svn_skel_t *conflict,
+ const struct dir_baton *pb,
+ const char *local_abspath,
+ const char *old_repos_relpath,
+ svn_revnum_t old_revision,
+ svn_node_kind_t kind,
+ apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+ const struct edit_baton *eb = pb->edit_baton;
+ svn_wc_conflict_version_t *src_left_version;
+ svn_boolean_t is_complete;
+
+ if (!conflict)
+ return SVN_NO_ERROR; /* Not conflicted */
+
+ SVN_ERR(svn_wc__conflict_skel_is_complete(&is_complete, conflict));
+
+ if (is_complete)
+ return SVN_NO_ERROR; /* Already competed */
+
+ if (old_repos_relpath)
+ src_left_version = svn_wc_conflict_version_create2(eb->repos_root,
+ eb->repos_uuid,
+ old_repos_relpath,
+ old_revision,
+ kind,
+ result_pool);
+ else
+ src_left_version = NULL;
+
+
+ if (eb->switch_relpath)
+ SVN_ERR(svn_wc__conflict_skel_set_op_switch(conflict,
+ src_left_version,
+ result_pool, scratch_pool));
+ else
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict,
+ src_left_version,
+ result_pool, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
/* Called when a directory is really edited, to avoid marking a
tree conflict on a node for a no-change edit */
static svn_error_t *
@@ -873,6 +923,11 @@ mark_directory_edited(struct dir_baton *
if (db->edit_conflict)
{
/* We have a (delayed) tree conflict to install */
+
+ SVN_ERR(complete_conflict(db->edit_conflict, db->parent_baton,
+ db->local_abspath, db->old_repos_relpath,
+ db->old_revision, svn_node_dir,
+ db->pool, scratch_pool));
SVN_ERR(svn_wc__db_op_mark_conflict(db->edit_baton->db,
db->local_abspath,
db->edit_conflict, NULL,
@@ -901,6 +956,12 @@ mark_file_edited(struct file_baton *fb,
if (fb->edit_conflict)
{
/* We have a (delayed) tree conflict to install */
+
+ SVN_ERR(complete_conflict(fb->edit_conflict, fb->dir_baton,
+ fb->local_abspath, fb->old_repos_relpath,
+ fb->old_revision, svn_node_file,
+ fb->pool, scratch_pool));
+
SVN_ERR(svn_wc__db_op_mark_conflict(fb->edit_baton->db,
fb->local_abspath,
fb->edit_conflict, NULL,
@@ -1285,136 +1346,9 @@ node_has_local_mods(svn_boolean_t *modif
return SVN_NO_ERROR;
}
-
/* Indicates an unset svn_wc_conflict_reason_t. */
#define SVN_WC_CONFLICT_REASON_NONE (svn_wc_conflict_reason_t)(-1)
-/* Create a tree conflict struct.
- *
- * The REASON is stored directly in the tree conflict info.
- *
- * All temporary allocations are be made in SCRATCH_POOL, while allocations
- * needed for the returned conflict struct are made in RESULT_POOL.
- *
- * All other parameters are identical to and described by
- * check_tree_conflict(), with the slight modification that this function
- * relies on the reason passed in REASON instead of actively looking for one. */
-static svn_error_t *
-create_tree_conflict(svn_skel_t **pconflict,
- struct edit_baton *eb,
- const char *local_abspath,
- svn_wc_conflict_reason_t reason,
- svn_wc_conflict_action_t action,
- apr_pool_t *result_pool, apr_pool_t *scratch_pool)
-{
- const char *left_repos_relpath;
- svn_revnum_t left_revision;
- svn_node_kind_t left_kind;
- svn_wc_conflict_version_t *src_left_version;
-
- *pconflict = NULL;
-
- SVN_ERR_ASSERT(reason != SVN_WC_CONFLICT_REASON_NONE);
-
- /* Get the source-left information, i.e. the local state of the node
- * before any changes were made to the working copy, i.e. the state the
- * node would have if it was reverted. */
- if (reason == svn_wc_conflict_reason_added ||
- reason == svn_wc_conflict_reason_moved_here)
- {
- /* ###TODO: It would be nice to tell the user at which URL and
- * ### revision source-left was empty, which could be quite difficult
- * ### to code, and is a slight theoretical leap of the svn mind.
- * ### Update should show
- * ### URL: svn_wc__db_scan_addition( &repos_relpath )
- * ### REV: The base revision of the parent of before this update
- * ### started
- * ### ### BUT what if parent was updated/switched away with
- * ### ### depth=empty after this node was added?
- * ### Switch should show
- * ### URL: scan_addition URL of before this switch started
- * ### REV: same as above */
-
- /* In case of a local addition, source-left is non-existent / empty. */
- left_kind = svn_node_none;
- left_revision = SVN_INVALID_REVNUM;
- left_repos_relpath = NULL;
- }
- else if (reason == svn_wc_conflict_reason_unversioned)
- {
- /* Obstructed by an unversioned node. Source-left is
- * non-existent/empty. */
- left_kind = svn_node_none;
- left_revision = SVN_INVALID_REVNUM;
- left_repos_relpath = NULL;
- }
- else
- {
- /* A BASE node should exist. */
- svn_kind_t base_kind;
-
- /* If anything else shows up, then this assertion is probably naive
- * and that other case should also be handled. */
- SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_edited
- || reason == svn_wc_conflict_reason_deleted
- || reason == svn_wc_conflict_reason_moved_away
- || reason == svn_wc_conflict_reason_moved_away_and_edited
- || reason == svn_wc_conflict_reason_replaced
- || reason == svn_wc_conflict_reason_obstructed);
-
- SVN_ERR(svn_wc__db_base_get_info(NULL, &base_kind,
- &left_revision,
- &left_repos_relpath,
- NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- eb->db, local_abspath,
- result_pool, scratch_pool));
- /* Translate the node kind. */
- if (base_kind == svn_kind_file
- || base_kind == svn_kind_symlink)
- left_kind = svn_node_file;
- else if (base_kind == svn_kind_dir)
- left_kind = svn_node_dir;
- else
- SVN_ERR_MALFUNCTION();
- }
-
- /* Construct the tree conflict info structs. */
-
- if (left_repos_relpath == NULL)
- /* A locally added or unversioned path in conflict with an incoming add.
- * Send an 'empty' left revision. */
- src_left_version = NULL;
- else
- src_left_version = svn_wc_conflict_version_create2(eb->repos_root,
- eb->repos_uuid,
- left_repos_relpath,
- left_revision,
- left_kind,
- result_pool);
-
- *pconflict = svn_wc__conflict_skel_create(result_pool);
-
- SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(*pconflict,
- eb->db, local_abspath,
- reason,
- action,
- result_pool, scratch_pool));
-
- if (eb->switch_relpath)
- SVN_ERR(svn_wc__conflict_skel_set_op_switch(*pconflict,
- src_left_version,
- result_pool, scratch_pool));
- else
- SVN_ERR(svn_wc__conflict_skel_set_op_update(*pconflict,
- src_left_version,
- result_pool, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
/* Check whether the incoming change ACTION on FULL_PATH would conflict with
* LOCAL_ABSPATH's scheduled change. If so, then raise a tree conflict with
* LOCAL_ABSPATH as the victim.
@@ -1431,7 +1365,7 @@ create_tree_conflict(svn_skel_t **pconfl
* while *PCONFLICT is always overwritten.
*
* The tree conflict is allocated in RESULT_POOL. Temporary allocations use
- * SCRACTH_POOl.
+ * SCRATCH_POOL.
*/
static svn_error_t *
check_tree_conflict(svn_skel_t **pconflict,
@@ -1609,11 +1543,16 @@ check_tree_conflict(svn_skel_t **pconfli
SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
- /* A conflict was detected. Append log commands to the log accumulator
- * to record it. */
- return svn_error_trace(create_tree_conflict(pconflict, eb, local_abspath,
- reason, action,
- result_pool, scratch_pool));
+ /* A conflict was detected. Create a conflict skel to record it. */
+ *pconflict = svn_wc__conflict_skel_create(result_pool);
+
+ SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(*pconflict,
+ eb->db, local_abspath,
+ reason,
+ action,
+ result_pool, scratch_pool));
+
+ return SVN_NO_ERROR;
}
@@ -1697,8 +1636,8 @@ delete_entry(const char *path,
const char *repos_relpath;
const char *moved_to_abspath = NULL;
svn_kind_t kind, base_kind;
+ svn_revnum_t old_revision;
svn_boolean_t conflicted;
- svn_boolean_t have_base;
svn_boolean_t have_work;
svn_skel_t *tree_conflict = NULL;
svn_wc__db_status_t status;
@@ -1739,11 +1678,11 @@ delete_entry(const char *path,
}
}
- SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, &repos_relpath, NULL, NULL,
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, &old_revision, &repos_relpath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
- NULL, NULL, NULL,
- &have_base, NULL, &have_work,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &conflicted, NULL, NULL, NULL,
+ NULL, NULL, &have_work,
eb->db, local_abspath,
scratch_pool, scratch_pool));
@@ -1753,7 +1692,7 @@ delete_entry(const char *path,
base_kind = kind;
}
else
- SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL,
+ SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, &old_revision,
&repos_relpath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
@@ -1884,6 +1823,13 @@ delete_entry(const char *path,
SVN_ERR(svn_io_remove_file2(moved_to_abspath, TRUE, scratch_pool));
}
+ SVN_ERR(complete_conflict(tree_conflict, pb, local_abspath, repos_relpath,
+ old_revision,
+ (kind == svn_kind_dir)
+ ? svn_node_dir
+ : svn_node_file,
+ pb->pool, scratch_pool));
+
/* Issue a wq operation to delete the BASE_NODE data and to delete actual
nodes based on that from disk, but leave any WORKING_NODEs on disk.
@@ -2108,11 +2054,10 @@ add_directory(const char *path,
/* And now stop checking for conflicts here and just perform
a shadowed update */
+ db->edit_conflict = tree_conflict; /* Cache for close_directory */
tree_conflict = NULL; /* No direct notification */
db->shadowed = TRUE; /* Just continue */
conflicted = FALSE; /* No skip */
-
- db->edit_conflict = tree_conflict; /* Cache for close_directory */
}
else
SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -2223,15 +2168,22 @@ add_directory(const char *path,
db->shadowed = TRUE;
/* Mark a conflict */
- SVN_ERR(create_tree_conflict(&tree_conflict, eb,
- db->local_abspath,
- svn_wc_conflict_reason_unversioned,
- svn_wc_conflict_action_add,
- pool, pool));
- SVN_ERR_ASSERT(tree_conflict != NULL);
+ tree_conflict = svn_wc__conflict_skel_create(db->pool);
+
+ SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+ tree_conflict,
+ eb->db, db->local_abspath,
+ svn_wc_conflict_reason_unversioned,
+ svn_wc_conflict_action_add,
+ db->pool, pool));
+ db->edit_conflict = tree_conflict;
}
}
+ SVN_ERR(complete_conflict(tree_conflict, pb, db->local_abspath,
+ db->old_repos_relpath, db->old_revision,
+ svn_node_dir, db->pool, pool));
+
SVN_ERR(svn_wc__db_base_add_incomplete_directory(
eb->db, db->local_abspath,
db->new_relpath,
@@ -2834,41 +2786,14 @@ close_directory(void *dir_baton,
if (conflict_skel)
{
svn_skel_t *work_item;
- svn_boolean_t completed;
- SVN_ERR(svn_wc__conflict_skel_is_complete(&completed,
- conflict_skel));
-
- if (completed)
- {
- /* Avoid assertion */
- }
- else if (eb->switch_relpath)
- SVN_ERR(svn_wc__conflict_skel_set_op_switch(
- conflict_skel,
- db->adding_dir
- ? NULL
- : svn_wc_conflict_version_create2(
- eb->repos_root,
- eb->repos_uuid,
- db->old_repos_relpath,
- db->old_revision,
- svn_node_dir,
- scratch_pool),
- db->pool, db->pool));
- else
- SVN_ERR(svn_wc__conflict_skel_set_op_update(
- conflict_skel,
- db->adding_dir
- ? NULL
- : svn_wc_conflict_version_create2(
- eb->repos_root,
- eb->repos_uuid,
- db->old_repos_relpath,
- db->old_revision,
- svn_node_dir,
- scratch_pool),
- db->pool, db->pool));
+ SVN_ERR(complete_conflict(conflict_skel,
+ db->parent_baton,
+ db->local_abspath,
+ db->old_repos_relpath,
+ db->old_revision,
+ svn_node_dir,
+ db->pool, scratch_pool));
SVN_ERR(svn_wc__conflict_create_markers(&work_item,
eb->db, db->local_abspath,
@@ -3261,11 +3186,10 @@ add_file(const char *path,
/* And now stop checking for conflicts here and just perform
a shadowed update */
+ fb->edit_conflict = tree_conflict; /* Cache for close_file */
tree_conflict = NULL; /* No direct notification */
fb->shadowed = TRUE; /* Just continue */
conflicted = FALSE; /* No skip */
-
- fb->edit_conflict = tree_conflict; /* Cache for close_file */
}
else
SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -3373,12 +3297,14 @@ add_file(const char *path,
fb->shadowed = TRUE;
/* Mark a conflict */
- SVN_ERR(create_tree_conflict(&tree_conflict, eb,
- fb->local_abspath,
- svn_wc_conflict_reason_unversioned,
- svn_wc_conflict_action_add,
- scratch_pool, scratch_pool));
- SVN_ERR_ASSERT(tree_conflict != NULL);
+ tree_conflict = svn_wc__conflict_skel_create(fb->pool);
+
+ SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+ tree_conflict,
+ eb->db, fb->local_abspath,
+ svn_wc_conflict_reason_unversioned,
+ svn_wc_conflict_action_add,
+ fb->pool, scratch_pool));
}
}
@@ -3395,6 +3321,14 @@ add_file(const char *path,
if (tree_conflict != NULL)
{
+ SVN_ERR(complete_conflict(tree_conflict,
+ fb->dir_baton,
+ fb->local_abspath,
+ fb->old_repos_relpath,
+ fb->old_revision,
+ svn_node_file,
+ fb->pool, scratch_pool));
+
SVN_ERR(svn_wc__db_op_mark_conflict(eb->db,
fb->local_abspath,
tree_conflict, NULL,
@@ -4462,39 +4396,13 @@ close_file(void *file_baton,
if (conflict_skel)
{
- svn_boolean_t completed;
-
- SVN_ERR(svn_wc__conflict_skel_is_complete(&completed,
- conflict_skel));
-
- if (completed)
- {
- /* Avoid assertion */
- }
- else if (eb->switch_relpath)
- SVN_ERR(svn_wc__conflict_skel_set_op_switch(
- conflict_skel,
- fb->adding_file
- ? NULL
- : svn_wc_conflict_version_create2(eb->repos_root,
- eb->repos_uuid,
- fb->old_repos_relpath,
- fb->old_revision,
- svn_node_file,
- fb->pool),
- fb->pool, fb->pool));
- else
- SVN_ERR(svn_wc__conflict_skel_set_op_update(
- conflict_skel,
- fb->adding_file
- ? NULL
- : svn_wc_conflict_version_create2(eb->repos_root,
- eb->repos_uuid,
- fb->old_repos_relpath,
- fb->old_revision,
- svn_node_file,
- fb->pool),
- fb->pool, fb->pool));
+ SVN_ERR(complete_conflict(conflict_skel,
+ fb->dir_baton,
+ fb->local_abspath,
+ fb->old_repos_relpath,
+ fb->old_revision,
+ svn_node_file,
+ fb->pool, scratch_pool));
SVN_ERR(svn_wc__conflict_create_markers(&work_item,
eb->db, fb->local_abspath,