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 2013/02/13 07:37:56 UTC
svn commit: r1445479 [7/11] - in /subversion/branches/fsfs-format7: ./
build/generator/ build/generator/swig/ build/generator/templates/
notes/api-errata/1.7/ packages/ subversion/bindings/swig/include/
subversion/bindings/swig/perl/libsvn_swig_perl/ s...
Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c Wed Feb 13 06:37:54 2013
@@ -219,15 +219,16 @@ mark_tree_conflict(struct tc_editor_bato
const char *old_repos_relpath,
svn_wc_conflict_reason_t reason,
svn_wc_conflict_action_t action,
- const char *moved_away_op_root_relpath,
- svn_skel_t *conflict,
+ const char *move_src_op_root_relpath,
apr_pool_t *scratch_pool)
{
+ svn_error_t *err;
+ svn_skel_t *conflict;
svn_wc_conflict_version_t *old_version, *new_version;
- const char *moved_away_op_root_abspath
- = moved_away_op_root_relpath
+ const char *move_src_op_root_abspath
+ = move_src_op_root_relpath
? svn_dirent_join(b->wcroot->abspath,
- moved_away_op_root_relpath, scratch_pool)
+ move_src_op_root_relpath, scratch_pool)
: NULL;
const char *old_repos_relpath_part
= old_repos_relpath
@@ -247,7 +248,62 @@ mark_tree_conflict(struct tc_editor_bato
local_relpath),
scratch_pool);
- if (!conflict)
+ err = svn_wc__db_read_conflict_internal(&conflict, b->wcroot, local_relpath,
+ scratch_pool, scratch_pool);
+ if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return err;
+ else if (err)
+ {
+ svn_error_clear(err);
+ conflict = NULL;
+ }
+
+ if (conflict)
+ {
+ svn_wc_operation_t operation;
+ svn_boolean_t tree_conflicted;
+
+ SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
+ &tree_conflicted,
+ b->db, b->wcroot->abspath, conflict,
+ scratch_pool, scratch_pool));
+
+ if (operation != svn_wc_operation_update
+ && operation != svn_wc_operation_switch)
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("'%s' already in conflict"),
+ svn_dirent_local_style(local_relpath,
+ scratch_pool));
+
+ if (tree_conflicted)
+ {
+ svn_wc_conflict_reason_t existing_reason;
+ svn_wc_conflict_action_t existing_action;
+ const char *existing_abspath;
+
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&existing_reason,
+ &existing_action,
+ &existing_abspath,
+ b->db, b->wcroot->abspath,
+ conflict,
+ scratch_pool,
+ scratch_pool));
+ if (reason != existing_reason
+ || action != existing_action
+ || (reason == svn_wc_conflict_reason_moved_away
+ && strcmp(move_src_op_root_relpath,
+ svn_dirent_skip_ancestor(b->wcroot->abspath,
+ existing_abspath))))
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("'%s' already in conflict"),
+ svn_dirent_local_style(local_relpath,
+ scratch_pool));
+
+ /* Already a suitable tree-conflict. */
+ return SVN_NO_ERROR;
+ }
+ }
+ else
conflict = svn_wc__conflict_skel_create(scratch_pool);
b->conflict_root_relpath = apr_pstrdup(b->result_pool, local_relpath);
@@ -258,7 +314,7 @@ mark_tree_conflict(struct tc_editor_bato
scratch_pool),
reason,
action,
- moved_away_op_root_abspath,
+ move_src_op_root_abspath,
scratch_pool,
scratch_pool));
@@ -322,9 +378,8 @@ check_tree_conflict(svn_boolean_t *is_co
int dst_op_depth = relpath_depth(b->move_root_dst_relpath);
int op_depth;
const char *conflict_root_relpath = local_relpath;
- const char *moved_to_relpath, *moved_to_op_root_relpath;
- const char *moved_away_op_root_relpath;
- svn_skel_t *conflict;
+ const char *move_dst_relpath, *dummy1;
+ const char *dummy2, *move_src_op_root_relpath;
if (b->conflict_root_relpath)
{
@@ -364,42 +419,21 @@ check_tree_conflict(svn_boolean_t *is_co
action = svn_wc_conflict_action_edit;
}
- SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, b->wcroot,
- conflict_root_relpath,
- scratch_pool, scratch_pool));
-
- if (conflict)
- {
- svn_error_t *err
- = svn_wc__conflict_read_tree_conflict(NULL, NULL, NULL,
- b->db, b->wcroot->abspath,
- conflict,
- scratch_pool, scratch_pool);
- if (err && err->apr_err != SVN_ERR_WC_MISSING)
- return err;
-
- if (!err)
- /* Already a tree-conflict. */
- return SVN_NO_ERROR;
-
- /* Not a tree-conflict. */
- svn_error_clear(err);
- }
-
- SVN_ERR(svn_wc__db_op_depth_moved_to(&moved_to_relpath,
- &moved_to_op_root_relpath,
- &moved_away_op_root_relpath,
+ SVN_ERR(svn_wc__db_op_depth_moved_to(&move_dst_relpath,
+ &dummy1,
+ &dummy2,
+ &move_src_op_root_relpath,
dst_op_depth,
b->wcroot, conflict_root_relpath,
scratch_pool, scratch_pool));
SVN_ERR(mark_tree_conflict(b, conflict_root_relpath, old_kind, new_kind,
old_repos_relpath,
- (moved_to_relpath
+ (move_dst_relpath
? svn_wc_conflict_reason_moved_away
: svn_wc_conflict_reason_deleted),
- action, moved_away_op_root_relpath,
- conflict, scratch_pool));
+ action, move_src_op_root_relpath,
+ scratch_pool));
if (b->notify_func)
SVN_ERR(update_move_list_add(b->wcroot, local_relpath,
svn_wc_notify_tree_conflict,
@@ -472,7 +506,7 @@ tc_editor_add_directory(void *baton,
SVN_ERR(mark_tree_conflict(b, relpath, old_kind, svn_node_dir,
move_dst_repos_relpath,
svn_wc_conflict_reason_unversioned,
- svn_wc_conflict_action_add, NULL, NULL,
+ svn_wc_conflict_action_add, NULL,
scratch_pool));
action = svn_wc_notify_tree_conflict;
break;
@@ -556,7 +590,7 @@ tc_editor_add_file(void *baton,
SVN_ERR(mark_tree_conflict(b, relpath, old_kind, svn_node_file,
move_dst_repos_relpath,
svn_wc_conflict_reason_unversioned,
- svn_wc_conflict_action_add, NULL, NULL,
+ svn_wc_conflict_action_add, NULL,
scratch_pool));
if (b->notify_func)
SVN_ERR(update_move_list_add(b->wcroot, relpath,
@@ -1072,7 +1106,7 @@ tc_editor_delete(void *baton,
is_conflicted = TRUE;
SVN_ERR(mark_tree_conflict(b, relpath, move_dst_kind, svn_node_none,
move_dst_repos_relpath, reason,
- svn_wc_conflict_action_delete, NULL, NULL,
+ svn_wc_conflict_action_delete, NULL,
scratch_pool));
if (b->notify_func)
SVN_ERR(update_move_list_add(b->wcroot, relpath,
@@ -1277,7 +1311,7 @@ static svn_error_t *
get_tc_info(svn_wc_operation_t *operation,
svn_wc_conflict_reason_t *local_change,
svn_wc_conflict_action_t *incoming_change,
- const char **moved_away_op_root_abspath,
+ const char **move_src_op_root_abspath,
svn_wc_conflict_version_t **old_version,
svn_wc_conflict_version_t **new_version,
svn_wc__db_t *db,
@@ -1306,7 +1340,9 @@ get_tc_info(svn_wc_operation_t *operatio
db, src_abspath,
conflict_skel, result_pool,
scratch_pool));
- if (!tree_conflicted)
+ if ((*operation != svn_wc_operation_update
+ && *operation != svn_wc_operation_switch)
+ || !tree_conflicted)
return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
_("'%s' is not a tree-conflict victim"),
svn_dirent_local_style(src_abspath,
@@ -1322,7 +1358,7 @@ get_tc_info(svn_wc_operation_t *operatio
SVN_ERR(svn_wc__conflict_read_tree_conflict(local_change,
incoming_change,
- moved_away_op_root_abspath,
+ move_src_op_root_abspath,
db, src_abspath,
conflict_skel, scratch_pool,
scratch_pool));
@@ -1689,6 +1725,62 @@ drive_tree_conflict_editor(svn_editor_t
return SVN_NO_ERROR;
}
+static svn_error_t *
+suitable_for_move(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ svn_revnum_t revision;
+ const char *repos_relpath;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ {
+ revision = svn_sqlite__column_revnum(stmt, 4);
+ repos_relpath = svn_sqlite__column_text(stmt, 1, scratch_pool);
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+ if (!have_row)
+ return SVN_NO_ERROR; /* Return an error? */
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_REPOS_PATH_REVISION));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ svn_revnum_t node_revision = svn_sqlite__column_revnum(stmt, 2);
+ const char *relpath = svn_sqlite__column_text(stmt, 0, NULL);
+
+ svn_pool_clear(iterpool);
+
+ relpath = svn_relpath_skip_ancestor(local_relpath, relpath);
+ relpath = svn_relpath_join(repos_relpath, relpath, iterpool);
+
+ if (revision != node_revision
+ || strcmp(relpath, svn_sqlite__column_text(stmt, 1, NULL)))
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
+ svn_sqlite__reset(stmt),
+ _("The tree '%s' is not single-revision and unswitched"),
+ svn_dirent_local_style(svn_dirent_join(wcroot->abspath,
+ local_relpath,
+ scratch_pool),
+ scratch_pool));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
/* The body of svn_wc__db_update_moved_away_conflict_victim(), which see.
*/
static svn_error_t *
@@ -1699,7 +1791,7 @@ update_moved_away_conflict_victim(svn_sk
svn_wc_operation_t operation,
svn_wc_conflict_reason_t local_change,
svn_wc_conflict_action_t incoming_change,
- const char *moved_away_op_root_relpath,
+ const char *move_src_op_root_relpath,
svn_wc_conflict_version_t *old_version,
svn_wc_conflict_version_t *new_version,
svn_wc_notify_func2_t notify_func,
@@ -1713,7 +1805,7 @@ update_moved_away_conflict_victim(svn_sk
struct tc_editor_baton *tc_editor_baton;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
- const char *dummy1, *dummy2;
+ const char *dummy1, *dummy2, *dummy3;
int src_op_depth;
/* ### assumes wc write lock already held */
@@ -1721,8 +1813,8 @@ update_moved_away_conflict_victim(svn_sk
/* Construct editor baton. */
tc_editor_baton = apr_pcalloc(scratch_pool, sizeof(*tc_editor_baton));
SVN_ERR(svn_wc__db_op_depth_moved_to(
- &dummy1, &tc_editor_baton->move_root_dst_relpath, &dummy2,
- relpath_depth(moved_away_op_root_relpath) - 1,
+ &dummy1, &tc_editor_baton->move_root_dst_relpath, &dummy2, &dummy3,
+ relpath_depth(move_src_op_root_relpath) - 1,
wcroot, victim_relpath, scratch_pool, scratch_pool));
if (tc_editor_baton->move_root_dst_relpath == NULL)
return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
@@ -1741,14 +1833,13 @@ update_moved_away_conflict_victim(svn_sk
tc_editor_baton->notify_baton = notify_baton;
tc_editor_baton->result_pool = result_pool;
- /* ### TODO get from svn_wc__db_op_depth_moved_to? */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_NODE_INFO));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, victim_relpath));
+ STMT_SELECT_HIGHEST_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ move_src_op_root_relpath,
+ relpath_depth(move_src_op_root_relpath)));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (have_row)
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (have_row)
src_op_depth = svn_sqlite__column_int(stmt, 0);
SVN_ERR(svn_sqlite__reset(stmt));
if (!have_row)
@@ -1759,6 +1850,9 @@ update_moved_away_conflict_victim(svn_sk
scratch_pool),
scratch_pool));
+ if (src_op_depth == 0)
+ SVN_ERR(suitable_for_move(wcroot, victim_relpath, scratch_pool));
+
/* Create a new, and empty, list for notification information. */
SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
STMT_CREATE_UPDATE_MOVE_LIST));
@@ -1803,10 +1897,10 @@ svn_wc__db_update_moved_away_conflict_vi
svn_wc_conflict_action_t incoming_change;
svn_wc_conflict_version_t *old_version;
svn_wc_conflict_version_t *new_version;
- const char *moved_away_op_root_abspath, *moved_away_op_root_relpath;
+ const char *move_src_op_root_abspath, *move_src_op_root_relpath;
SVN_ERR(get_tc_info(&operation, &local_change, &incoming_change,
- &moved_away_op_root_abspath,
+ &move_src_op_root_abspath,
&old_version, &new_version,
db, victim_abspath,
scratch_pool, scratch_pool));
@@ -1816,14 +1910,14 @@ svn_wc__db_update_moved_away_conflict_vi
scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- moved_away_op_root_relpath
- = svn_dirent_skip_ancestor(wcroot->abspath, moved_away_op_root_abspath);
+ move_src_op_root_relpath
+ = svn_dirent_skip_ancestor(wcroot->abspath, move_src_op_root_abspath);
SVN_WC__DB_WITH_TXN(
update_moved_away_conflict_victim(
work_items, db, wcroot, local_relpath,
operation, local_change, incoming_change,
- moved_away_op_root_relpath,
+ move_src_op_root_relpath,
old_version, new_version,
notify_func, notify_baton,
cancel_func, cancel_baton,
@@ -1981,7 +2075,7 @@ resolve_delete_raise_moved_away(svn_wc__
svn_node_dir /* ### ? */,
moved_dst_repos_relpath,
svn_wc_conflict_reason_moved_away,
- action, local_relpath, NULL, iterpool));
+ action, local_relpath, iterpool));
/* ### Do notification? */
@@ -2024,3 +2118,59 @@ svn_wc__db_resolve_delete_raise_moved_aw
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ const char *dummy1, *move_dst_op_root_relpath;
+ const char *dummy2, *move_src_op_root_relpath;
+ svn_sqlite__stmt_t *stmt;
+ int dst_op_depth;
+
+ SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath,
+ &dummy2,
+ &move_src_op_root_relpath,
+ relpath_depth(local_relpath) - 1,
+ wcroot, local_relpath,
+ scratch_pool, scratch_pool));
+ dst_op_depth = relpath_depth(move_dst_op_root_relpath);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_CLEAR_MOVED_TO_RELPATH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+ relpath_depth(move_src_op_root_relpath)));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ /* This statement clears moved_here. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_UPDATE_OP_DEPTH_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id,
+ move_dst_op_root_relpath,
+ dst_op_depth, dst_op_depth));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_resolve_break_moved_away(svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_wcroot_t *wcroot;
+ const char *local_relpath;
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ SVN_WC__DB_WITH_TXN(
+ svn_wc__db_resolve_break_moved_away_internal(wcroot, local_relpath,
+ scratch_pool),
+ wcroot);
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/deadprops.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/deadprops.c Wed Feb 13 06:37:54 2013
@@ -170,6 +170,7 @@ save_value(dav_db *db, const dav_prop_na
const char *propname;
svn_error_t *serr;
const dav_resource *resource = db->resource;
+ apr_pool_t *subpool;
/* get the repos-local name */
get_repos_propname(db, name, &propname);
@@ -204,13 +205,16 @@ save_value(dav_db *db, const dav_prop_na
*/
+ /* A subpool to cope with mod_dav making multiple calls, e.g. during
+ PROPPATCH with multiple values. */
+ subpool = svn_pool_create(db->resource->pool);
if (db->resource->baselined)
{
if (db->resource->working)
{
serr = svn_repos_fs_change_txn_prop(resource->info->root.txn,
propname, value,
- resource->pool);
+ subpool);
}
else
{
@@ -221,7 +225,7 @@ save_value(dav_db *db, const dav_prop_na
TRUE, TRUE,
db->authz_read_func,
db->authz_read_baton,
- resource->pool);
+ subpool);
/* Prepare any hook failure message to get sent over the wire */
if (serr)
@@ -244,20 +248,21 @@ save_value(dav_db *db, const dav_prop_na
dav_svn__operational_log(resource->info,
svn_log__change_rev_prop(
resource->info->root.rev,
- propname, resource->pool));
+ propname, subpool));
}
}
else if (resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION)
{
serr = svn_repos_fs_change_txn_prop(resource->info->root.txn,
- propname, value, resource->pool);
+ propname, value, subpool);
}
else
{
serr = svn_repos_fs_change_node_prop(resource->info->root.root,
get_repos_path(resource->info),
- propname, value, resource->pool);
+ propname, value, subpool);
}
+ svn_pool_destroy(subpool);
if (serr != NULL)
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -538,6 +543,7 @@ db_remove(dav_db *db, const dav_prop_nam
{
svn_error_t *serr;
const char *propname;
+ apr_pool_t *subpool;
/* get the repos-local name */
get_repos_propname(db, name, &propname);
@@ -546,11 +552,15 @@ db_remove(dav_db *db, const dav_prop_nam
if (propname == NULL)
return NULL;
+ /* A subpool to cope with mod_dav making multiple calls, e.g. during
+ PROPPATCH with multiple values. */
+ subpool = svn_pool_create(db->resource->pool);
+
/* Working Baseline or Working (Version) Resource */
if (db->resource->baselined)
if (db->resource->working)
serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn,
- propname, NULL, db->resource->pool);
+ propname, NULL, subpool);
else
/* ### VIOLATING deltaV: you can't proppatch a baseline, it's
not a working resource! But this is how we currently
@@ -562,11 +572,12 @@ db_remove(dav_db *db, const dav_prop_nam
propname, NULL, NULL, TRUE, TRUE,
db->authz_read_func,
db->authz_read_baton,
- db->resource->pool);
+ subpool);
else
serr = svn_repos_fs_change_node_prop(db->resource->info->root.root,
get_repos_path(db->resource->info),
- propname, NULL, db->resource->pool);
+ propname, NULL, subpool);
+ svn_pool_destroy(subpool);
if (serr != NULL)
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"could not remove a property",