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/03 17:30:32 UTC
svn commit: r1356789 - in /subversion/trunk/subversion:
libsvn_client/merge.c libsvn_wc/conflicts.c libsvn_wc/wc_db.c
libsvn_wc/wc_db.h
Author: rhuijben
Date: Tue Jul 3 15:30:29 2012
New Revision: 1356789
URL: http://svn.apache.org/viewvc?rev=1356789&view=rev
Log:
Switch the remaining pieces of the wc_db api to using conflict skels for
transfering conflicts. Reconstruct conflict descriptors in
svn_wc__read_conflicts().
* subversion/libsvn_client/merge.c
(tree_conflict,
merge_file_added): Remove assumption that you can retrieve conflicts
on non-existing paths without an error.
* subversion/libsvn_wc/conflicts.c
(svn_wc__read_conflicts): Create conflict descriptors from the skel from
wc_db.
* subversion/libsvn_wc/wc_db.c
(includes): Document that we only need tree_conflicts.h for non skel mode.
(svn_wc__db_read_conflicts): Rename to ...
(svn_wc__db_read_conflict): ... this and return the conflict as a non-const
skel.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_read_conflicts): Rename to ...
(svn_wc__db_read_conflict): ... this and update documentation.
Modified:
subversion/trunk/subversion/libsvn_client/merge.c
subversion/trunk/subversion/libsvn_wc/conflicts.c
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Tue Jul 3 15:30:29 2012
@@ -661,13 +661,24 @@ tree_conflict(merge_cmd_baton_t *merge_b
svn_wc_conflict_reason_t reason)
{
const svn_wc_conflict_description2_t *existing_conflict;
+ svn_error_t *err;
if (merge_b->record_only || merge_b->dry_run)
return SVN_NO_ERROR;
- SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict, merge_b->ctx->wc_ctx,
- victim_abspath, merge_b->pool,
- merge_b->pool));
+ err = svn_wc__get_tree_conflict(&existing_conflict, merge_b->ctx->wc_ctx,
+ victim_abspath, merge_b->pool,
+ merge_b->pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ existing_conflict = FALSE;
+ }
+
if (existing_conflict == NULL)
{
svn_wc_conflict_description2_t *conflict;
@@ -1869,6 +1880,7 @@ merge_file_added(svn_wc_notify_state_t *
svn_stream_t *new_contents, *new_base_contents;
apr_hash_t *new_base_props, *new_props;
const svn_wc_conflict_description2_t *existing_conflict;
+ svn_error_t *err;
/* If this is a merge from the same repository as our
working copy, we handle adds as add-with-history.
@@ -1904,10 +1916,20 @@ merge_file_added(svn_wc_notify_state_t *
scratch_pool, scratch_pool));
}
- SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict,
- merge_b->ctx->wc_ctx,
- mine_abspath, merge_b->pool,
- merge_b->pool));
+ err = svn_wc__get_tree_conflict(&existing_conflict,
+ merge_b->ctx->wc_ctx,
+ mine_abspath, merge_b->pool,
+ merge_b->pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ existing_conflict = FALSE;
+ }
+
if (existing_conflict)
{
svn_boolean_t moved_here;
Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Tue Jul 3 15:30:29 2012
@@ -1798,10 +1798,165 @@ svn_wc__read_conflicts(const apr_array_h
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_error_trace(
- svn_wc__db_read_conflicts(conflicts,
- db, local_abspath,
- result_pool, scratch_pool));
+ svn_skel_t *conflict_skel;
+ apr_array_header_t *cflcts;
+ svn_boolean_t prop_conflicted;
+ svn_boolean_t text_conflicted;
+ svn_boolean_t tree_conflicted;
+ svn_wc_operation_t operation;
+ const apr_array_header_t *locations;
+ svn_error_t *err;
+
+ SVN_ERR(svn_wc__db_read_conflict(&conflict_skel, db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (!conflict_skel)
+ {
+ /* Some callers expect not NULL */
+ *conflicts = apr_array_make(result_pool, 0,
+ sizeof(svn_wc_conflict_description2_t*));;
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, &text_conflicted,
+ &prop_conflicted, &tree_conflicted,
+ db, local_abspath, conflict_skel,
+ scratch_pool, scratch_pool));
+
+ cflcts = apr_array_make(result_pool, 4,
+ sizeof(svn_wc_conflict_description2_t*));
+
+ if (prop_conflicted)
+ {
+ svn_wc_conflict_description2_t *desc;
+ desc = svn_wc_conflict_description_create_prop2(local_abspath,
+ svn_node_unknown,
+ "",
+ result_pool);
+
+ SVN_ERR(svn_wc__conflict_read_prop_conflict(&desc->their_abspath,
+ NULL, NULL, NULL, NULL,
+ db, local_abspath,
+ conflict_skel,
+ result_pool, scratch_pool));
+
+ APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
+ }
+
+ if (text_conflicted)
+ {
+ svn_wc_conflict_description2_t *desc;
+ desc = svn_wc_conflict_description_create_text2(local_abspath,
+ result_pool);
+
+ SVN_ERR(svn_wc__conflict_read_text_conflict(&desc->my_abspath,
+ &desc->base_abspath,
+ &desc->their_abspath,
+ db, local_abspath,
+ conflict_skel,
+ result_pool, scratch_pool));
+
+ desc->merged_file = apr_pstrdup(result_pool, local_abspath);
+
+ APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
+ }
+
+ if (tree_conflicted)
+ {
+ svn_wc_conflict_description2_t *desc;
+ svn_wc_conflict_version_t *v1;
+ svn_wc_conflict_version_t *v2;
+ svn_node_kind_t tc_kind;
+ svn_wc_conflict_reason_t local_change;
+ svn_wc_conflict_action_t incoming_change;
+
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
+ &incoming_change,
+ db, local_abspath,
+ conflict_skel,
+ scratch_pool, scratch_pool));
+
+ v1 = (locations && locations->nelts > 0)
+ ? APR_ARRAY_IDX(locations, 0, svn_wc_conflict_version_t *)
+ : NULL;
+
+ v2 = (locations && locations->nelts > 1)
+ ? APR_ARRAY_IDX(locations, 1, svn_wc_conflict_version_t *)
+ : NULL;
+
+ if (incoming_change != svn_wc_conflict_action_delete
+ && (operation == svn_wc_operation_update
+ || operation == svn_wc_operation_switch))
+ {
+ svn_wc__db_status_t status;
+ svn_revnum_t revision;
+ const char *repos_relpath;
+ const char *repos_root_url;
+ const char *repos_uuid;
+ svn_kind_t kind;
+ svn_error_t *err;
+
+ /* ### Theoretically we should just fetch the BASE information
+ here. This code might need tweaks until all tree conflicts
+ are installed in the proper state */
+
+ SVN_ERR_ASSERT(v2 == NULL); /* Not set for update and switch */
+
+ /* With an update or switch we have to fetch the second location
+ for a tree conflict from WORKING. (For text or prop from BASE)
+ */
+ err = svn_wc__db_base_get_info(&status, &kind, &revision,
+ &repos_relpath, &repos_root_url,
+ &repos_uuid, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool);
+
+ if (err)
+ {
+ if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ /* Ignore BASE */
+
+ tc_kind = svn_node_file; /* Avoid assertion */
+ }
+ else if (repos_relpath)
+ {
+ v2 = svn_wc_conflict_version_create2(repos_root_url,
+ repos_uuid,
+ repos_relpath,
+ revision,
+ svn__node_kind_from_kind(kind),
+ scratch_pool);
+ tc_kind = svn__node_kind_from_kind(kind);
+ }
+ else
+ tc_kind = svn_node_file; /* Avoid assertion */
+ }
+ else
+ {
+ if (v1)
+ tc_kind = v1->node_kind;
+ else if (v2)
+ tc_kind = v2->node_kind;
+ else
+ tc_kind = svn_node_file; /* Avoid assertion */
+ }
+
+ desc = svn_wc_conflict_description_create_tree2(local_abspath, tc_kind,
+ operation, v1, v2,
+ result_pool);
+
+ desc->reason = local_change;
+ desc->action = incoming_change;
+
+ APR_ARRAY_PUSH(cflcts, const svn_wc_conflict_description2_t *) = desc;
+ }
+
+ *conflicts = cflcts;
+ return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Jul 3 15:30:29 2012
@@ -43,7 +43,9 @@
#include "entries.h"
#include "lock.h"
#include "conflicts.h"
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
#include "tree_conflicts.h"
+#endif
#include "wc_db_private.h"
#include "workqueue.h"
@@ -5247,8 +5249,6 @@ mark_conflict(svn_wc__db_wcroot_t *wcroo
svn_boolean_t text_conflict;
svn_boolean_t prop_conflict;
svn_boolean_t tree_conflict;
- svn_wc_conflict_reason_t local_change;
- svn_wc_conflict_action_t incoming_change;
const apr_array_header_t *locations;
svn_wc_operation_t operation;
@@ -5336,6 +5336,8 @@ mark_conflict(svn_wc__db_wcroot_t *wcroo
svn_wc_conflict_version_t *v2;
svn_node_kind_t tc_kind;
svn_skel_t *skel;
+ svn_wc_conflict_reason_t local_change;
+ svn_wc_conflict_action_t incoming_change;
SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
&incoming_change,
@@ -11610,115 +11612,195 @@ svn_wc__db_get_conflict_marker_files(apr
svn_error_t *
-svn_wc__db_read_conflicts(const apr_array_header_t **conflicts,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_wc__db_read_conflict(svn_skel_t **conflict,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_wc__db_wcroot_t *wcroot;
const char *local_relpath;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
- apr_array_header_t *cflcts;
/* The parent should be a working copy directory. */
SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
local_abspath, scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- /* ### This will be much easier once we have all conflicts in one
- field of actual.*/
-
- /* First look for text and property conflicts in ACTUAL */
+ /* Check if we have a conflict in ACTUAL */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_ACTUAL_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
- cflcts = apr_array_make(result_pool, 4,
- sizeof(svn_wc_conflict_description2_t*));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (have_row)
+ if (! have_row)
{
-#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
- const char *prop_reject;
- const char *conflict_old;
- const char *conflict_new;
- const char *conflict_working;
- const char *conflict_data;
-
- /* ### Store in description! */
- prop_reject = svn_sqlite__column_text(stmt, 6, NULL);
- if (prop_reject)
- {
- svn_wc_conflict_description2_t *desc;
+ /* Do this while stmt is still open to avoid closing the sqlite
+ transaction and then reopening. */
+ svn_sqlite__stmt_t *stmt_node;
+ svn_error_t *err;
- desc = svn_wc_conflict_description_create_prop2(local_abspath,
- svn_node_unknown,
- "",
- result_pool);
+ err = svn_sqlite__get_statement(&stmt_node, wcroot->sdb,
+ STMT_SELECT_NODE_INFO);
- desc->their_abspath = svn_dirent_join(wcroot->abspath, prop_reject,
- result_pool);
+ if (err)
+ stmt_node = NULL;
+ else
+ err = svn_sqlite__bindf(stmt_node, "is", wcroot->wc_id,
+ local_relpath);
- APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
- }
+ if (!err)
+ err = svn_sqlite__step(&have_row, stmt_node);
- conflict_old = svn_sqlite__column_text(stmt, 3, NULL);
- conflict_new = svn_sqlite__column_text(stmt, 4, NULL);
- conflict_working = svn_sqlite__column_text(stmt, 5, NULL);
+ if (stmt_node)
+ err = svn_error_compose_create(err,
+ svn_sqlite__reset(stmt_node));
+
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
- if (conflict_old || conflict_new || conflict_working)
+ if (have_row)
{
- svn_wc_conflict_description2_t *desc
- = svn_wc_conflict_description_create_text2(local_abspath,
- result_pool);
+ *conflict = NULL;
+ return SVN_NO_ERROR;
+ }
- if (conflict_old)
- desc->base_abspath = svn_dirent_join(wcroot->abspath, conflict_old,
- result_pool);
- if (conflict_new)
- desc->their_abspath = svn_dirent_join(wcroot->abspath, conflict_new,
- result_pool);
- if (conflict_working)
- desc->my_abspath = svn_dirent_join(wcroot->abspath,
- conflict_working, result_pool);
- desc->merged_file = apr_pstrdup(result_pool, local_abspath);
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
+ path_for_error_message(wcroot,
+ local_relpath,
+ scratch_pool));
+ }
- APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
- }
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
+ {
+ const char *conflict_old = svn_sqlite__column_text(stmt, 3, NULL);
+ const char *conflict_new = svn_sqlite__column_text(stmt, 4, NULL);
+ const char *conflict_wrk = svn_sqlite__column_text(stmt, 5, NULL);
+ const char *conflict_prj = svn_sqlite__column_text(stmt, 6, NULL);
+ const char *tree_conflict = svn_sqlite__column_text(stmt, 7, NULL);
+ svn_skel_t *conflict_skel = NULL;
+ svn_error_t *err = NULL;
- conflict_data = svn_sqlite__column_text(stmt, 7, scratch_pool);
- if (conflict_data)
- {
- const svn_wc_conflict_description2_t *desc;
- const svn_skel_t *skel;
- svn_error_t *err;
+ if (conflict_old || conflict_new || conflict_wrk)
+ {
+ conflict_skel = svn_wc__conflict_skel_create(result_pool);
- skel = svn_skel__parse(conflict_data, strlen(conflict_data),
- scratch_pool);
- err = svn_wc__deserialize_conflict(&desc, skel,
+ if (conflict_old)
+ conflict_old = svn_dirent_join(wcroot->abspath, conflict_old,
+ scratch_pool);
+
+ if (conflict_new)
+ conflict_new = svn_dirent_join(wcroot->abspath, conflict_new,
+ scratch_pool);
+
+ if (conflict_wrk)
+ conflict_wrk = svn_dirent_join(wcroot->abspath, conflict_wrk,
+ scratch_pool);
+
+ err = svn_wc__conflict_skel_add_text_conflict(conflict_skel,
+ db, local_abspath,
+ conflict_wrk,
+ conflict_old,
+ conflict_new,
+ result_pool,
+ scratch_pool);
+ }
+
+ if (!err && conflict_prj)
+ {
+ if (!conflict_skel)
+ conflict_skel = svn_wc__conflict_skel_create(result_pool);
+
+ if (conflict_prj)
+ conflict_prj = svn_dirent_join(wcroot->abspath, conflict_prj,
+ scratch_pool);
+
+ err = svn_wc__conflict_skel_add_prop_conflict(conflict_skel,
+ db, local_abspath,
+ conflict_prj,
+ NULL, NULL, NULL,
+ apr_hash_make(scratch_pool),
+ result_pool,
+ scratch_pool);
+ }
+
+ if (!err && tree_conflict)
+ {
+ const svn_wc_conflict_description2_t *tc;
+ const svn_skel_t *tc_skel;
+ if (!conflict_skel)
+ conflict_skel = svn_wc__conflict_skel_create(result_pool);
+
+ tc_skel = svn_skel__parse(tree_conflict, strlen(tree_conflict),
+ scratch_pool);
+ err = svn_wc__deserialize_conflict(
+ &tc, tc_skel,
svn_dirent_dirname(local_abspath, scratch_pool),
- result_pool, scratch_pool);
+ scratch_pool, scratch_pool);
- if (err)
- SVN_ERR(svn_error_compose_create(err,
- svn_sqlite__reset(stmt)));
+ if (!err)
+ err = svn_wc__conflict_skel_add_tree_conflict(conflict_skel,
+ db, local_abspath,
+ tc->reason,
+ tc->action,
+ result_pool,
+ scratch_pool);
+
+ if (!err)
+ switch (tc->operation)
+ {
+ case svn_wc_operation_merge:
+ err = svn_wc__conflict_skel_set_op_merge(conflict_skel,
+ tc->src_left_version,
+ tc->src_right_version,
+ result_pool,
+ scratch_pool);
+ break;
+ case svn_wc_operation_update:
+ default:
+ err = svn_wc__conflict_skel_set_op_update(conflict_skel,
+ tc->src_left_version,
+ result_pool,
+ scratch_pool);
+ break;
+ case svn_wc_operation_switch:
+ err = svn_wc__conflict_skel_set_op_switch(conflict_skel,
+ tc->src_left_version,
+ result_pool,
+ scratch_pool);
+ break;
+ }
+ }
+ else if (!err && conflict_skel)
+ {
+ err = svn_wc__conflict_skel_set_op_update(conflict_skel, NULL,
+ result_pool, scratch_pool);
+ }
- APR_ARRAY_PUSH(cflcts, const svn_wc_conflict_description2_t *) = desc;
- }
+ if (err)
+ return svn_error_trace(
+ svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+ *conflict = conflict_skel;
+ }
#else
- SVN_ERR_MALFUNCTION();
-#endif
- }
+ {
+ apr_size_t cfl_len;
+ const void *cfl_data;
- SVN_ERR(svn_sqlite__reset(stmt));
+ /* svn_skel__parse doesn't copy data, so store in result_pool */
+ cfl_data = svn_sqlite__column_blob(stmt, 2, &cfl_len, result_pool);
- *conflicts = cflcts;
+ if (cfl_data)
+ *conflict = svn_skel__parse(cfl_data, cfl_len, result_pool);
+ else
+ *conflict = NULL;
+ }
+#endif
- return SVN_NO_ERROR;
+ return svn_error_trace(svn_sqlite__reset(stmt));
}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue Jul 3 15:30:29 2012
@@ -2119,22 +2119,20 @@ svn_wc__db_get_conflict_marker_files(apr
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Read into CONFLICTS svn_wc_conflict_description2_t* structs
- for all conflicts that have LOCAL_ABSPATH as victim.
+/* Read the conflict information recorded on LOCAL_ABSPATH in *CONFLICT,
+ an editable conflict skel.
- Victim must be versioned or be part of a tree conflict.
+ If the node exists, but does not have a conflict set *CONFLICT to NULL,
+ otherwise return a SVN_ERR_WC_PATH_NOT_FOUND error.
Allocate *CONFLICTS in RESULT_POOL and do temporary allocations in
SCRATCH_POOL */
-/* ### Currently there can be just one property conflict recorded
- per victim */
-/* ### This function will probably be removed. */
svn_error_t *
-svn_wc__db_read_conflicts(const apr_array_header_t **conflicts,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
+svn_wc__db_read_conflict(svn_skel_t **conflict,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* Return the kind of the node in DB at LOCAL_ABSPATH. The WORKING tree will