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/11/27 09:19:51 UTC
svn commit: r1545958 [9/15] - in /subversion/branches/log-addressing: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ contrib/server-side/ contrib/server-side/svncutter/ notes/
subversion/bindings/javahl/native/ subv...
Modified: subversion/branches/log-addressing/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_wc/wc_db_update_move.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_wc/wc_db_update_move.c Wed Nov 27 08:19:45 2013
@@ -91,7 +91,6 @@
#include "private/svn_skel.h"
#include "private/svn_sqlite.h"
#include "private/svn_wc_private.h"
-#include "private/svn_editor.h"
#include "wc.h"
#include "props.h"
@@ -114,7 +113,7 @@
* be made at the move destination.
*/
-struct tc_editor_baton {
+typedef struct update_move_baton_t {
svn_wc__db_t *db;
svn_wc__db_wcroot_t *wcroot;
const char *move_root_dst_relpath;
@@ -127,7 +126,7 @@ struct tc_editor_baton {
svn_wc_conflict_version_t *old_version;
svn_wc_conflict_version_t *new_version;
apr_pool_t *result_pool; /* For things that live as long as the baton. */
-};
+} update_move_baton_t;
/*
* Notifications are delayed until the entire update-move transaction
@@ -251,11 +250,14 @@ mark_tree_conflict(const char *local_rel
: NULL;
if (!new_repos_relpath)
- new_repos_relpath
- = svn_relpath_join(new_version->path_in_repos,
- svn_relpath_skip_ancestor(move_root_dst_relpath,
- local_relpath),
- scratch_pool);
+ {
+ const char *child_relpath = svn_relpath_skip_ancestor(
+ move_root_dst_relpath,
+ local_relpath);
+ SVN_ERR_ASSERT(child_relpath != NULL);
+ new_repos_relpath = svn_relpath_join(new_version->path_in_repos,
+ child_relpath, scratch_pool);
+ }
err = svn_wc__db_read_conflict_internal(&conflict, wcroot, local_relpath,
scratch_pool, scratch_pool);
@@ -303,7 +305,7 @@ mark_tree_conflict(const char *local_rel
&& strcmp(move_src_op_root_relpath,
svn_dirent_skip_ancestor(wcroot->abspath,
existing_abspath))))
- return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
_("'%s' already in conflict"),
svn_dirent_local_style(local_relpath,
scratch_pool));
@@ -366,6 +368,35 @@ mark_tree_conflict(const char *local_rel
return SVN_NO_ERROR;
}
+/* Checks if a specific local path is shadowed as seen from the move root */
+static svn_error_t *
+check_node_shadowed(svn_boolean_t *shadowed,
+ update_move_baton_t *b,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ int op_depth = -1;
+ *shadowed = FALSE;
+
+ /* ### This should really be optimized by using something smart
+ in the baton */
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", b->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (have_row)
+ op_depth = svn_sqlite__column_int(stmt, 0);
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ *shadowed = (op_depth > relpath_depth(b->move_root_dst_relpath));
+
+ return SVN_NO_ERROR;
+}
+
/* If LOCAL_RELPATH is a child of the most recently raised
tree-conflict or is shadowed then set *IS_CONFLICTED to TRUE and
raise a tree-conflict on the root of the obstruction if such a
@@ -374,7 +405,7 @@ mark_tree_conflict(const char *local_rel
drive. */
static svn_error_t *
check_tree_conflict(svn_boolean_t *is_conflicted,
- struct tc_editor_baton *b,
+ update_move_baton_t *b,
const char *local_relpath,
svn_node_kind_t old_kind,
svn_node_kind_t new_kind,
@@ -452,15 +483,12 @@ check_tree_conflict(svn_boolean_t *is_co
}
static svn_error_t *
-tc_editor_add_directory(void *baton,
+tc_editor_add_directory(update_move_baton_t *b,
const char *relpath,
- const apr_array_header_t *children,
apr_hash_t *props,
- svn_revnum_t replaces_rev,
+ svn_boolean_t shadowed,
apr_pool_t *scratch_pool)
{
- struct tc_editor_baton *b = baton;
- int op_depth = relpath_depth(b->move_root_dst_relpath);
const char *move_dst_repos_relpath;
svn_node_kind_t move_dst_kind;
svn_boolean_t is_conflicted;
@@ -472,9 +500,6 @@ tc_editor_add_directory(void *baton,
/* Update NODES, only the bits not covered by the later call to
replace_moved_layer. */
- SVN_ERR(svn_wc__db_extend_parent_delete(b->wcroot, relpath, svn_node_dir,
- op_depth, scratch_pool));
-
err = svn_wc__db_depth_get_info(NULL, &move_dst_kind, NULL,
&move_dst_repos_relpath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
@@ -499,7 +524,7 @@ tc_editor_add_directory(void *baton,
move_dst_repos_relpath,
svn_wc_conflict_action_add,
scratch_pool));
- if (is_conflicted)
+ if (is_conflicted || shadowed)
return SVN_NO_ERROR;
/* Check for unversioned tree-conflict */
@@ -543,16 +568,13 @@ tc_editor_add_directory(void *baton,
}
static svn_error_t *
-tc_editor_add_file(void *baton,
+tc_editor_add_file(update_move_baton_t *b,
const char *relpath,
const svn_checksum_t *checksum,
- svn_stream_t *contents,
apr_hash_t *props,
- svn_revnum_t replaces_rev,
+ svn_boolean_t shadowed,
apr_pool_t *scratch_pool)
{
- struct tc_editor_baton *b = baton;
- int op_depth = relpath_depth(b->move_root_dst_relpath);
const char *move_dst_repos_relpath;
svn_node_kind_t move_dst_kind;
svn_node_kind_t old_kind;
@@ -563,9 +585,6 @@ tc_editor_add_file(void *baton,
/* Update NODES, only the bits not covered by the later call to
replace_moved_layer. */
- SVN_ERR(svn_wc__db_extend_parent_delete(b->wcroot, relpath, svn_node_file,
- op_depth, scratch_pool));
-
err = svn_wc__db_depth_get_info(NULL, &move_dst_kind, NULL,
&move_dst_repos_relpath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
@@ -589,7 +608,7 @@ tc_editor_add_file(void *baton,
old_kind, svn_node_file, move_dst_repos_relpath,
svn_wc_conflict_action_add,
scratch_pool));
- if (is_conflicted)
+ if (is_conflicted || shadowed)
return SVN_NO_ERROR;
/* Check for unversioned tree-conflict */
@@ -630,27 +649,6 @@ tc_editor_add_file(void *baton,
return SVN_NO_ERROR;
}
-static svn_error_t *
-tc_editor_add_symlink(void *baton,
- const char *relpath,
- const char *target,
- apr_hash_t *props,
- svn_revnum_t replaces_rev,
- apr_pool_t *scratch_pool)
-{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
-}
-
-static svn_error_t *
-tc_editor_add_absent(void *baton,
- const char *relpath,
- svn_node_kind_t kind,
- svn_revnum_t replaces_rev,
- apr_pool_t *scratch_pool)
-{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
-}
-
/* All the info we need about one version of a working node. */
typedef struct working_node_version_t
{
@@ -721,8 +719,8 @@ update_working_props(svn_wc_notify_state
svn_skel_t **conflict_skel,
apr_array_header_t **propchanges,
apr_hash_t **actual_props,
- svn_wc__db_t *db,
- const char *local_abspath,
+ update_move_baton_t *b,
+ const char *local_relpath,
const struct working_node_version_t *old_version,
const struct working_node_version_t *new_version,
apr_pool_t *result_pool,
@@ -737,49 +735,47 @@ update_working_props(svn_wc_notify_state
* 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,
- result_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_props_internal(actual_props,
+ b->wcroot, local_relpath,
+ result_pool, scratch_pool));
SVN_ERR(svn_prop_diffs(propchanges, new_version->props, old_version->props,
result_pool));
SVN_ERR(svn_wc__merge_props(conflict_skel, prop_state,
&new_actual_props,
- db, local_abspath,
+ b->db, svn_dirent_join(b->wcroot->abspath,
+ local_relpath,
+ scratch_pool),
old_version->props, old_version->props,
*actual_props, *propchanges,
result_pool, scratch_pool));
- /* Setting properties in ACTUAL_NODE with svn_wc__db_op_set_props
- relies on NODES row having been updated first which we don't do
- at present. So this extra property diff has the same effect.
+ /* Setting properties in ACTUAL_NODE with svn_wc__db_op_set_props_internal
+ relies on NODES row being updated via a different route .
- ### Perhaps we should update NODES first (but after
- ### svn_wc__db_read_props above)? */
+ This extra property diff makes sure we clear the actual row when
+ the final result is unchanged properties. */
SVN_ERR(svn_prop_diffs(&new_propchanges, new_actual_props, new_version->props,
scratch_pool));
if (!new_propchanges->nelts)
new_actual_props = NULL;
- /* Install the new actual props. Don't set the conflict_skel yet, because
- we might need to add a text conflict to it as well. */
- 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));
+ /* Install the new actual props. */
+ SVN_ERR(svn_wc__db_op_set_props_internal(b->wcroot, local_relpath,
+ new_actual_props,
+ svn_wc__has_magic_property(
+ *propchanges),
+ scratch_pool));
return SVN_NO_ERROR;
}
static svn_error_t *
-tc_editor_alter_directory(void *baton,
+tc_editor_alter_directory(update_move_baton_t *b,
const char *dst_relpath,
- svn_revnum_t expected_move_dst_revision,
- const apr_array_header_t *children,
apr_hash_t *new_props,
+ svn_boolean_t shadowed,
apr_pool_t *scratch_pool)
{
- struct tc_editor_baton *b = baton;
const char *move_dst_repos_relpath;
svn_revnum_t move_dst_revision;
svn_node_kind_t move_dst_kind;
@@ -787,8 +783,6 @@ tc_editor_alter_directory(void *baton,
svn_wc__db_status_t status;
svn_boolean_t is_conflicted;
- SVN_ERR_ASSERT(expected_move_dst_revision == b->old_version->peg_rev);
-
SVN_ERR(svn_wc__db_depth_get_info(&status, &move_dst_kind, &move_dst_revision,
&move_dst_repos_relpath, NULL, NULL, NULL,
NULL, NULL, &old_version.checksum, NULL,
@@ -797,17 +791,10 @@ tc_editor_alter_directory(void *baton,
relpath_depth(b->move_root_dst_relpath),
scratch_pool, scratch_pool));
- /* If the node would be recorded as svn_wc__db_status_base_deleted it
- wouldn't have a repos_relpath */
- /* ### Can svn_wc__db_depth_get_info() do this for us without this hint? */
- if (status == svn_wc__db_status_deleted && move_dst_repos_relpath)
- status = svn_wc__db_status_not_present;
/* There might be not-present nodes of a different revision as the same
depth as a copy. This is commonly caused by copying/moving mixed revision
directories */
- SVN_ERR_ASSERT(move_dst_revision == expected_move_dst_revision
- || status == svn_wc__db_status_not_present);
SVN_ERR_ASSERT(move_dst_kind == svn_node_dir);
SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath,
@@ -816,7 +803,7 @@ tc_editor_alter_directory(void *baton,
move_dst_repos_relpath,
svn_wc_conflict_action_edit,
scratch_pool));
- if (is_conflicted)
+ if (is_conflicted || shadowed)
return SVN_NO_ERROR;
old_version.location_and_kind = b->old_version;
@@ -835,9 +822,10 @@ tc_editor_alter_directory(void *baton,
apr_hash_t *actual_props;
apr_array_header_t *propchanges;
+ /* ### TODO: Only do this when there is no higher WORKING layer */
SVN_ERR(update_working_props(&prop_state, &conflict_skel,
&propchanges, &actual_props,
- b->db, dst_abspath,
+ b, dst_relpath,
&old_version, &new_version,
scratch_pool, scratch_pool));
@@ -884,16 +872,15 @@ tc_editor_alter_directory(void *baton,
* Set *WORK_ITEMS to any required work items, allocated in RESULT_POOL.
* Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
-update_working_file(const char *local_relpath,
+update_working_file(update_move_baton_t *b,
+ const char *local_relpath,
const char *repos_relpath,
svn_wc_operation_t operation,
const working_node_version_t *old_version,
const working_node_version_t *new_version,
- svn_wc__db_wcroot_t *wcroot,
- svn_wc__db_t *db,
apr_pool_t *scratch_pool)
{
- const char *local_abspath = svn_dirent_join(wcroot->abspath,
+ const char *local_abspath = svn_dirent_join(b->wcroot->abspath,
local_relpath,
scratch_pool);
const char *old_pristine_abspath;
@@ -905,8 +892,9 @@ update_working_file(const char *local_re
svn_wc_notify_state_t prop_state, content_state;
svn_skel_t *work_item, *work_items = NULL;
+ /* ### TODO: Only do this when there is no higher WORKING layer */
SVN_ERR(update_working_props(&prop_state, &conflict_skel, &propchanges,
- &actual_props, db, local_abspath,
+ &actual_props, b, local_relpath,
old_version, new_version,
scratch_pool, scratch_pool));
@@ -915,12 +903,12 @@ update_working_file(const char *local_re
svn_boolean_t is_locally_modified;
SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
- db, local_abspath,
+ b->db, local_abspath,
FALSE /* exact_comparison */,
scratch_pool));
if (!is_locally_modified)
{
- SVN_ERR(svn_wc__wq_build_file_install(&work_item, db,
+ SVN_ERR(svn_wc__wq_build_file_install(&work_item, b->db,
local_abspath,
NULL,
FALSE /* FIXME: use_commit_times? */,
@@ -940,15 +928,15 @@ update_working_file(const char *local_re
* moved-here working file as the merge-right version.
*/
SVN_ERR(svn_wc__db_pristine_get_path(&old_pristine_abspath,
- db, wcroot->abspath,
+ b->db, b->wcroot->abspath,
old_version->checksum,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_pristine_get_path(&new_pristine_abspath,
- db, wcroot->abspath,
+ b->db, b->wcroot->abspath,
new_version->checksum,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__internal_merge(&work_item, &conflict_skel,
- &merge_outcome, db,
+ &merge_outcome, b->db,
old_pristine_abspath,
new_pristine_abspath,
local_abspath,
@@ -977,22 +965,23 @@ update_working_file(const char *local_re
* too. */
if (conflict_skel)
{
- SVN_ERR(create_conflict_markers(&work_item, local_abspath, db,
+ SVN_ERR(create_conflict_markers(&work_item, local_abspath, b->db,
repos_relpath, conflict_skel,
operation, old_version, new_version,
svn_node_file,
scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
+ SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, local_relpath,
conflict_skel,
scratch_pool));
work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
}
- SVN_ERR(svn_wc__db_wq_add(db, wcroot->abspath, work_items, scratch_pool));
+ SVN_ERR(svn_wc__db_wq_add(b->db, b->wcroot->abspath, work_items,
+ scratch_pool));
- SVN_ERR(update_move_list_add(wcroot, local_relpath,
+ SVN_ERR(update_move_list_add(b->wcroot, local_relpath,
svn_wc_notify_update_update,
svn_node_file,
content_state,
@@ -1006,15 +995,13 @@ update_working_file(const char *local_re
* the old state. Merge the changes into the "working"/"actual" file.
*/
static svn_error_t *
-tc_editor_alter_file(void *baton,
+tc_editor_alter_file(update_move_baton_t *b,
const char *dst_relpath,
- svn_revnum_t expected_move_dst_revision,
const svn_checksum_t *new_checksum,
- svn_stream_t *new_contents,
apr_hash_t *new_props,
+ svn_boolean_t shadowed,
apr_pool_t *scratch_pool)
{
- struct tc_editor_baton *b = baton;
const char *move_dst_repos_relpath;
svn_revnum_t move_dst_revision;
svn_node_kind_t move_dst_kind;
@@ -1030,14 +1017,6 @@ tc_editor_alter_file(void *baton,
relpath_depth(b->move_root_dst_relpath),
scratch_pool, scratch_pool));
- /* If the node would be recorded as svn_wc__db_status_base_deleted it
- wouldn't have a repos_relpath */
- /* ### Can svn_wc__db_depth_get_info() do this for us without this hint? */
- if (status == svn_wc__db_status_deleted && move_dst_repos_relpath)
- status = svn_wc__db_status_not_present;
-
- SVN_ERR_ASSERT(move_dst_revision == expected_move_dst_revision
- || status == svn_wc__db_status_not_present);
SVN_ERR_ASSERT(move_dst_kind == svn_node_file);
SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath,
@@ -1046,7 +1025,7 @@ tc_editor_alter_file(void *baton,
move_dst_repos_relpath,
svn_wc_conflict_action_edit,
scratch_pool));
- if (is_conflicted)
+ if (is_conflicted || shadowed)
return SVN_NO_ERROR;
old_version.location_and_kind = b->old_version;
@@ -1059,9 +1038,8 @@ tc_editor_alter_file(void *baton,
/* Update file and prop contents if the update has changed them. */
if (!svn_checksum_match(new_checksum, old_version.checksum) || new_props)
{
- SVN_ERR(update_working_file(dst_relpath, move_dst_repos_relpath,
+ SVN_ERR(update_working_file(b, dst_relpath, move_dst_repos_relpath,
b->operation, &old_version, &new_version,
- b->wcroot, b->db,
scratch_pool));
}
@@ -1069,40 +1047,25 @@ tc_editor_alter_file(void *baton,
}
static svn_error_t *
-tc_editor_alter_symlink(void *baton,
- const char *relpath,
- svn_revnum_t revision,
- const char *target,
- apr_hash_t *props,
- apr_pool_t *scratch_pool)
-{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
-}
-
-static svn_error_t *
-tc_editor_delete(void *baton,
+tc_editor_delete(update_move_baton_t *b,
const char *relpath,
- svn_revnum_t revision,
+ svn_boolean_t shadowed,
apr_pool_t *scratch_pool)
{
- struct tc_editor_baton *b = baton;
svn_sqlite__stmt_t *stmt;
int op_depth = relpath_depth(b->move_root_dst_relpath);
const char *move_dst_repos_relpath;
svn_node_kind_t move_dst_kind;
svn_boolean_t is_conflicted;
svn_boolean_t must_delete_working_nodes = FALSE;
- const char *local_abspath = svn_dirent_join(b->wcroot->abspath, relpath,
- scratch_pool);
- const char *parent_relpath = svn_relpath_dirname(relpath, scratch_pool);
- int op_depth_below;
+ const char *local_abspath;
svn_boolean_t have_row;
+ svn_boolean_t is_modified, is_all_deletes;
SVN_ERR(svn_wc__db_depth_get_info(NULL, &move_dst_kind, NULL,
&move_dst_repos_relpath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
- b->wcroot, relpath,
- relpath_depth(b->move_root_dst_relpath),
+ b->wcroot, relpath, op_depth,
scratch_pool, scratch_pool));
/* Check before retracting delete to catch delete-delete
@@ -1115,52 +1078,51 @@ tc_editor_delete(void *baton,
svn_wc_conflict_action_delete,
scratch_pool));
- if (!is_conflicted)
+ if (shadowed || is_conflicted)
+ return SVN_NO_ERROR;
+
+ local_abspath = svn_dirent_join(b->wcroot->abspath, relpath, scratch_pool);
+ SVN_ERR(svn_wc__node_has_local_mods(&is_modified, &is_all_deletes, b->db,
+ local_abspath,
+ NULL, NULL, scratch_pool));
+ if (is_modified)
{
- svn_boolean_t is_modified, is_all_deletes;
+ svn_wc_conflict_reason_t reason;
- SVN_ERR(svn_wc__node_has_local_mods(&is_modified, &is_all_deletes, b->db,
- local_abspath,
- NULL, NULL, scratch_pool));
- if (is_modified)
+ if (!is_all_deletes)
{
- svn_wc_conflict_reason_t reason;
-
- if (!is_all_deletes)
- {
- /* No conflict means no NODES rows at the relpath op-depth
- so it's easy to convert the modified tree into a copy. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
- STMT_UPDATE_OP_DEPTH_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isdd", b->wcroot->wc_id, relpath,
- op_depth, relpath_depth(relpath)));
- SVN_ERR(svn_sqlite__step_done(stmt));
+ /* No conflict means no NODES rows at the relpath op-depth
+ so it's easy to convert the modified tree into a copy. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_UPDATE_OP_DEPTH_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdd", b->wcroot->wc_id, relpath,
+ op_depth, relpath_depth(relpath)));
+ SVN_ERR(svn_sqlite__step_done(stmt));
- reason = svn_wc_conflict_reason_edited;
- }
- else
- {
+ reason = svn_wc_conflict_reason_edited;
+ }
+ else
+ {
- SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
- STMT_DELETE_WORKING_OP_DEPTH_ABOVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, relpath,
- op_depth));
- SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_DELETE_WORKING_OP_DEPTH_ABOVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, relpath,
+ op_depth));
+ SVN_ERR(svn_sqlite__step_done(stmt));
- reason = svn_wc_conflict_reason_deleted;
- must_delete_working_nodes = TRUE;
- }
- is_conflicted = TRUE;
- SVN_ERR(mark_tree_conflict(relpath, b->wcroot, b->db, b->old_version,
- b->new_version, b->move_root_dst_relpath,
- b->operation,
- move_dst_kind,
- svn_node_none,
- move_dst_repos_relpath, reason,
- svn_wc_conflict_action_delete, NULL,
- scratch_pool));
- b->conflict_root_relpath = apr_pstrdup(b->result_pool, relpath);
+ reason = svn_wc_conflict_reason_deleted;
+ must_delete_working_nodes = TRUE;
}
+ is_conflicted = TRUE;
+ SVN_ERR(mark_tree_conflict(relpath, b->wcroot, b->db, b->old_version,
+ b->new_version, b->move_root_dst_relpath,
+ b->operation,
+ move_dst_kind,
+ svn_node_none,
+ move_dst_repos_relpath, reason,
+ svn_wc_conflict_action_delete, NULL,
+ scratch_pool));
+ b->conflict_root_relpath = apr_pstrdup(b->result_pool, relpath);
}
if (!is_conflicted || must_delete_working_nodes)
@@ -1229,6 +1191,20 @@ tc_editor_delete(void *baton,
svn_wc_notify_state_inapplicable));
svn_pool_destroy(iterpool);
}
+ return SVN_NO_ERROR;
+}
+
+/* Delete handling for both WORKING and shadowed nodes */
+static svn_error_t *
+delete_move_leaf(update_move_baton_t *b,
+ const char *relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ int op_depth = relpath_depth(b->move_root_dst_relpath);
+ const char *parent_relpath = svn_relpath_dirname(relpath, scratch_pool);
+ svn_boolean_t have_row;
+ int op_depth_below;
/* Deleting the ROWS is valid so long as we update the parent before
committing the transaction. The removed rows could have been
@@ -1274,58 +1250,6 @@ tc_editor_delete(void *baton,
return SVN_NO_ERROR;
}
-static svn_error_t *
-tc_editor_copy(void *baton,
- const char *src_relpath,
- svn_revnum_t src_revision,
- const char *dst_relpath,
- svn_revnum_t replaces_rev,
- apr_pool_t *scratch_pool)
-{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
-}
-
-static svn_error_t *
-tc_editor_move(void *baton,
- const char *src_relpath,
- svn_revnum_t src_revision,
- const char *dst_relpath,
- svn_revnum_t replaces_rev,
- apr_pool_t *scratch_pool)
-{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
-}
-
-static svn_error_t *
-tc_editor_complete(void *baton,
- apr_pool_t *scratch_pool)
-{
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-tc_editor_abort(void *baton,
- apr_pool_t *scratch_pool)
-{
- return SVN_NO_ERROR;
-}
-
-/* The editor callback table implementing the receiver. */
-static const svn_editor_cb_many_t editor_ops = {
- tc_editor_add_directory,
- tc_editor_add_file,
- tc_editor_add_symlink,
- tc_editor_add_absent,
- tc_editor_alter_directory,
- tc_editor_alter_file,
- tc_editor_alter_symlink,
- tc_editor_delete,
- tc_editor_copy,
- tc_editor_move,
- tc_editor_complete,
- tc_editor_abort
-};
-
/*
* Driver code.
@@ -1407,9 +1331,9 @@ get_tc_info(svn_wc_operation_t *operatio
/* Return *PROPS, *CHECKSUM, *CHILDREN and *KIND for LOCAL_RELPATH at
OP_DEPTH provided the row exists. Return *KIND of svn_node_none if
- the row does not exist. *CHILDREN is a sorted array of basenames of
- type 'const char *', rather than a hash, to allow the driver to
- process children in a defined order. */
+ the row does not exist, or only describes a delete of a lower op-depth.
+ *CHILDREN is a sorted array of basenames of type 'const char *', rather
+ than a hash, to allow the driver to process children in a defined order. */
static svn_error_t *
get_info(apr_hash_t **props,
const svn_checksum_t **checksum,
@@ -1424,16 +1348,36 @@ get_info(apr_hash_t **props,
apr_hash_t *hash_children;
apr_array_header_t *sorted_children;
svn_error_t *err;
+ svn_wc__db_status_t status;
+ const char *repos_relpath;
int i;
- err = svn_wc__db_depth_get_info(NULL, kind, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, checksum, NULL, NULL, props,
+ err = svn_wc__db_depth_get_info(&status, kind, NULL, &repos_relpath, NULL,
+ NULL, NULL, NULL, NULL, checksum, NULL,
+ NULL, props,
wcroot, local_relpath, op_depth,
result_pool, scratch_pool);
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+
+ /* If there is no node at this depth, or only a node that describes a delete
+ of a lower layer we report this node as not existing.
+
+ But when a node is reported as DELETED, but has a repository location it
+ is really a not-present node that must be reported as being there */
+ if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ || (!err && status == svn_wc__db_status_deleted))
{
svn_error_clear(err);
- *kind = svn_node_none;
+
+ if (kind && (err || !repos_relpath))
+ *kind = svn_node_none;
+ if (checksum)
+ *checksum = NULL;
+ if (props)
+ *props = NULL;
+ if (children)
+ *children = apr_array_make(result_pool, 0, sizeof(const char *));
+
+ return SVN_NO_ERROR;
}
else
SVN_ERR(err);
@@ -1507,14 +1451,14 @@ props_match(svn_boolean_t *match,
/* ### Drive TC_EDITOR so as to ...
*/
static svn_error_t *
-update_moved_away_node(svn_editor_t *tc_editor,
+update_moved_away_node(update_move_baton_t *b,
+ svn_wc__db_wcroot_t *wcroot,
const char *src_relpath,
const char *dst_relpath,
int src_op_depth,
const char *move_root_dst_relpath,
- svn_revnum_t move_root_dst_revision,
+ svn_boolean_t shadowed,
svn_wc__db_t *db,
- svn_wc__db_wcroot_t *wcroot,
apr_pool_t *scratch_pool)
{
svn_node_kind_t src_kind, dst_kind;
@@ -1534,28 +1478,33 @@ update_moved_away_node(svn_editor_t *tc_
if (src_kind == svn_node_none
|| (dst_kind != svn_node_none && src_kind != dst_kind))
{
- SVN_ERR(svn_editor_delete(tc_editor, dst_relpath,
- move_root_dst_revision));
+ SVN_ERR(tc_editor_delete(b, dst_relpath, shadowed,
+ scratch_pool));
+
+ /* And perform some work that in some ways belongs in
+ replace_moved_layer() after creating all conflicts */
+ SVN_ERR(delete_move_leaf(b, dst_relpath, scratch_pool));
}
if (src_kind != svn_node_none && src_kind != dst_kind)
{
+ if (shadowed)
+ {
+ SVN_ERR(svn_wc__db_extend_parent_delete(
+ b->wcroot, dst_relpath, src_kind,
+ relpath_depth(b->move_root_dst_relpath),
+ scratch_pool));
+ }
if (src_kind == svn_node_file || src_kind == svn_node_symlink)
{
- svn_stream_t *contents;
-
- SVN_ERR(svn_wc__db_pristine_read(&contents, NULL, db,
- wcroot->abspath, src_checksum,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_editor_add_file(tc_editor, dst_relpath,
- src_checksum, contents, src_props,
- move_root_dst_revision));
+ SVN_ERR(tc_editor_add_file(b, dst_relpath,
+ src_checksum, src_props,
+ shadowed, scratch_pool));
}
else if (src_kind == svn_node_dir)
{
- SVN_ERR(svn_editor_add_directory(tc_editor, dst_relpath,
- src_children, src_props,
- move_root_dst_revision));
+ SVN_ERR(tc_editor_add_directory(b, dst_relpath, src_props,
+ shadowed, scratch_pool));
}
}
else if (src_kind != svn_node_none)
@@ -1569,22 +1518,14 @@ update_moved_away_node(svn_editor_t *tc_
if (src_kind == svn_node_file || src_kind == svn_node_symlink)
{
- svn_stream_t *contents;
-
if (svn_checksum_match(src_checksum, dst_checksum))
src_checksum = NULL;
- if (src_checksum)
- SVN_ERR(svn_wc__db_pristine_read(&contents, NULL, db,
- wcroot->abspath, src_checksum,
- scratch_pool, scratch_pool));
- else
- contents = NULL;
-
if (props || src_checksum)
- SVN_ERR(svn_editor_alter_file(tc_editor, dst_relpath,
- move_root_dst_revision,
- src_checksum, contents, props));
+ SVN_ERR(tc_editor_alter_file(b, dst_relpath,
+ src_checksum, props,
+ shadowed,
+ scratch_pool));
}
else if (src_kind == svn_node_dir)
{
@@ -1592,9 +1533,9 @@ update_moved_away_node(svn_editor_t *tc_
= children_match(src_children, dst_children) ? NULL : src_children;
if (props || children)
- SVN_ERR(svn_editor_alter_directory(tc_editor, dst_relpath,
- move_root_dst_revision,
- children, props));
+ SVN_ERR(tc_editor_alter_directory(b, dst_relpath, props,
+ shadowed,
+ scratch_pool));
}
}
@@ -1608,6 +1549,7 @@ update_moved_away_node(svn_editor_t *tc_
const char *child_name;
const char *src_child_relpath, *dst_child_relpath;
svn_boolean_t src_only = FALSE, dst_only = FALSE;
+ svn_boolean_t child_shadowed = shadowed;
svn_pool_clear(iterpool);
if (i >= src_children->nelts)
@@ -1641,11 +1583,14 @@ update_moved_away_node(svn_editor_t *tc_
dst_child_relpath = svn_relpath_join(dst_relpath, child_name,
iterpool);
- SVN_ERR(update_moved_away_node(tc_editor, src_child_relpath,
+ if (!child_shadowed)
+ SVN_ERR(check_node_shadowed(&child_shadowed, b, dst_child_relpath,
+ iterpool));
+
+ SVN_ERR(update_moved_away_node(b, wcroot, src_child_relpath,
dst_child_relpath, src_op_depth,
- move_root_dst_relpath,
- move_root_dst_revision,
- db, wcroot, scratch_pool));
+ move_root_dst_relpath, child_shadowed,
+ db, iterpool));
if (!dst_only)
++i;
@@ -1710,7 +1655,7 @@ replace_moved_layer(const char *src_relp
/* Transfer changes from the move source to the move destination.
*
- * Drive the editor TC_EDITOR with the difference between DST_RELPATH
+ * Drive the editor with the difference between DST_RELPATH
* (at its own op-depth) and SRC_RELPATH (at op-depth zero).
*
* Then update the single op-depth layer in the move destination subtree
@@ -1720,7 +1665,7 @@ replace_moved_layer(const char *src_relp
* ### And the other params?
*/
static svn_error_t *
-drive_tree_conflict_editor(svn_editor_t *tc_editor,
+drive_tree_conflict_editor(update_move_baton_t *b,
const char *src_relpath,
const char *dst_relpath,
int src_op_depth,
@@ -1751,16 +1696,14 @@ drive_tree_conflict_editor(svn_editor_t
/* We walk the move source (i.e. the post-update tree), comparing each node
* with the equivalent node at the move destination and applying the update
* to nodes at the move destination. */
- SVN_ERR(update_moved_away_node(tc_editor, src_relpath, dst_relpath,
+ SVN_ERR(update_moved_away_node(b, wcroot, src_relpath, dst_relpath,
src_op_depth,
- dst_relpath, old_version->peg_rev,
- db, wcroot, scratch_pool));
+ dst_relpath, FALSE /* never shadowed */,
+ db, scratch_pool));
SVN_ERR(replace_moved_layer(src_relpath, dst_relpath, src_op_depth,
wcroot, scratch_pool));
- SVN_ERR(svn_editor_complete(tc_editor));
-
return SVN_NO_ERROR;
}
@@ -1779,14 +1722,13 @@ suitable_for_move(svn_wc__db_wcroot_t *w
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? */
+ return svn_error_trace(svn_sqlite__reset(stmt));
+
+ revision = svn_sqlite__column_revnum(stmt, 4);
+ repos_relpath = svn_sqlite__column_text(stmt, 1, scratch_pool);
+
+ SVN_ERR(svn_sqlite__reset(stmt));
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_REPOS_PATH_REVISION));
@@ -1849,8 +1791,7 @@ update_moved_away_conflict_victim(svn_wc
void *cancel_baton,
apr_pool_t *scratch_pool)
{
- svn_editor_t *tc_editor;
- struct tc_editor_baton *tc_editor_baton;
+ update_move_baton_t umb;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
const char *dummy1, *dummy2, *dummy3;
@@ -1860,12 +1801,12 @@ update_moved_away_conflict_victim(svn_wc
/* ### assumes wc write lock already held */
/* Construct editor baton. */
- tc_editor_baton = apr_pcalloc(scratch_pool, sizeof(*tc_editor_baton));
+ memset(&umb, 0, sizeof(umb));
SVN_ERR(svn_wc__db_op_depth_moved_to(
- &dummy1, &tc_editor_baton->move_root_dst_relpath, &dummy2, &dummy3,
+ &dummy1, &umb.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)
+ if (umb.move_root_dst_relpath == NULL)
return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
_("The node '%s' has not been moved away"),
svn_dirent_local_style(
@@ -1874,16 +1815,16 @@ update_moved_away_conflict_victim(svn_wc
scratch_pool));
move_root_dst_abspath
- = svn_dirent_join(wcroot->abspath, tc_editor_baton->move_root_dst_relpath,
+ = svn_dirent_join(wcroot->abspath, umb.move_root_dst_relpath,
scratch_pool);
SVN_ERR(svn_wc__write_check(db, move_root_dst_abspath, scratch_pool));
- tc_editor_baton->operation = operation;
- tc_editor_baton->old_version= old_version;
- tc_editor_baton->new_version= new_version;
- tc_editor_baton->db = db;
- tc_editor_baton->wcroot = wcroot;
- tc_editor_baton->result_pool = scratch_pool;
+ umb.operation = operation;
+ umb.old_version= old_version;
+ umb.new_version= new_version;
+ umb.db = db;
+ umb.wcroot = wcroot;
+ umb.result_pool = scratch_pool;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_HIGHEST_WORKING_NODE));
@@ -1909,20 +1850,16 @@ update_moved_away_conflict_victim(svn_wc
SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
STMT_CREATE_UPDATE_MOVE_LIST));
/* Create the editor... */
- SVN_ERR(svn_editor_create(&tc_editor, tc_editor_baton,
- cancel_func, cancel_baton,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_editor_setcb_many(tc_editor, &editor_ops, scratch_pool));
/* ... and drive it. */
- SVN_ERR(drive_tree_conflict_editor(tc_editor,
+ SVN_ERR(drive_tree_conflict_editor(&umb,
victim_relpath,
- tc_editor_baton->move_root_dst_relpath,
+ umb.move_root_dst_relpath,
src_op_depth,
operation,
local_change, incoming_change,
- tc_editor_baton->old_version,
- tc_editor_baton->new_version,
+ umb.old_version,
+ umb.new_version,
db, wcroot,
cancel_func, cancel_baton,
scratch_pool));
@@ -2008,11 +1945,12 @@ svn_wc__db_update_moved_away_conflict_vi
}
/* Set *CAN_BUMP to TRUE if DEPTH is sufficient to cover the entire
- BASE tree at LOCAL_RELPATH, to FALSE otherwise. */
+ tree LOCAL_RELPATH at OP_DEPTH, to FALSE otherwise. */
static svn_error_t *
depth_sufficient_to_bump(svn_boolean_t *can_bump,
- const char *local_relpath,
svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ int op_depth,
svn_depth_t depth,
apr_pool_t *scratch_pool)
{
@@ -2029,21 +1967,21 @@ depth_sufficient_to_bump(svn_boolean_t *
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_OP_DEPTH_CHILDREN));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
- local_relpath, 0));
+ local_relpath, op_depth));
break;
case svn_depth_files:
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_HAS_NON_FILE_CHILDREN));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
- local_relpath));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ local_relpath, op_depth));
break;
case svn_depth_immediates:
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_HAS_GRANDCHILDREN));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
- local_relpath));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ local_relpath, op_depth));
break;
default:
SVN_ERR_MALFUNCTION();
@@ -2115,10 +2053,149 @@ bump_mark_tree_conflict(svn_wc__db_wcroo
return SVN_NO_ERROR;
}
-/* Bump LOCAL_RELPATH, and all the children of LOCAL_RELPATH, that are
- moved-to at op-depth greater than OP_DEPTH. SRC_DONE is a hash
- with keys that are 'const char *' relpaths that have already been
- bumped. Any bumped paths are added to SRC_DONE. */
+/* Checks if SRC_RELPATH is within BUMP_DEPTH from BUMP_ROOT. Sets
+ * *SKIP to TRUE if the node should be skipped, otherwise to FALSE.
+ * Sets *SRC_DEPTH to the remaining depth at SRC_RELPATH.
+ */
+static svn_error_t *
+check_bump_layer(svn_boolean_t *skip,
+ svn_depth_t *src_depth,
+ const char *bump_root,
+ svn_depth_t bump_depth,
+ const char *src_relpath,
+ svn_node_kind_t src_kind,
+ apr_pool_t *scratch_pool)
+{
+ const char *relpath;
+
+ *skip = FALSE;
+ *src_depth = bump_depth;
+
+ relpath = svn_relpath_skip_ancestor(bump_root, src_relpath);
+
+ if (!relpath)
+ *skip = TRUE;
+
+ if (bump_depth == svn_depth_infinity)
+ return SVN_NO_ERROR;
+
+ if (relpath && *relpath == '\0')
+ return SVN_NO_ERROR;
+
+ switch (bump_depth)
+ {
+ case svn_depth_empty:
+ *skip = TRUE;
+ break;
+
+ case svn_depth_files:
+ if (src_kind != svn_node_file)
+ {
+ *skip = TRUE;
+ break;
+ }
+ /* Fallthrough */
+ case svn_depth_immediates:
+ if (!relpath || relpath_depth(relpath) > 1)
+ *skip = TRUE;
+
+ *src_depth = svn_depth_empty;
+ break;
+ default:
+ SVN_ERR_MALFUNCTION();
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* The guts of bump_moved_away: Determines if a move can be bumped to match
+ * the move origin and if so performs this bump.
+ */
+static svn_error_t *
+bump_moved_layer(svn_boolean_t *recurse,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ int op_depth,
+ const char *src_relpath,
+ int src_op_depth,
+ svn_node_kind_t src_kind,
+ svn_depth_t src_depth,
+ const char *dst_relpath,
+ apr_hash_t *src_done,
+ svn_wc__db_t *db,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ svn_skel_t *conflict;
+ svn_boolean_t can_bump;
+ const char *src_root_relpath = src_relpath;
+
+ *recurse = FALSE;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_HAS_LAYER_BETWEEN));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, local_relpath,
+ op_depth, src_op_depth));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (have_row)
+ return SVN_NO_ERROR;
+
+ if (op_depth == 0)
+ SVN_ERR(depth_sufficient_to_bump(&can_bump, wcroot, src_relpath,
+ op_depth, src_depth, scratch_pool));
+ else
+ /* Having chosen to bump an entire BASE tree move we
+ always have sufficient depth to bump subtree moves. */
+ can_bump = TRUE;
+
+ if (!can_bump)
+ {
+ SVN_ERR(bump_mark_tree_conflict(wcroot, src_relpath,
+ src_root_relpath, dst_relpath,
+ db, scratch_pool));
+
+ return SVN_NO_ERROR;
+ }
+
+ while (relpath_depth(src_root_relpath) > src_op_depth)
+ src_root_relpath = svn_relpath_dirname(src_root_relpath, scratch_pool);
+
+
+ if (svn_hash_gets(src_done, src_relpath))
+ return SVN_NO_ERROR;
+
+ svn_hash_sets(src_done, apr_pstrdup(result_pool, src_relpath), "");
+
+ SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, wcroot,
+ src_root_relpath,
+ scratch_pool, scratch_pool));
+
+ /* ### TODO: check this is the right sort of tree-conflict? */
+ if (!conflict)
+ {
+ /* ### TODO: verify moved_here? */
+ SVN_ERR(replace_moved_layer(src_relpath, dst_relpath,
+ op_depth, wcroot, scratch_pool));
+
+ *recurse = TRUE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Bump moves of LOCAL_RELPATH and all its descendants that were
+ originally below LOCAL_RELPATH at op-depth OP_DEPTH.
+
+ SRC_DONE is a hash with keys that are 'const char *' relpaths
+ that have already been bumped. Any bumped paths are added to
+ SRC_DONE. */
static svn_error_t *
bump_moved_away(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
@@ -2132,6 +2209,7 @@ bump_moved_away(svn_wc__db_wcroot_t *wcr
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
apr_pool_t *iterpool;
+ svn_error_t *err = NULL;
iterpool = svn_pool_create(scratch_pool);
@@ -2142,130 +2220,51 @@ bump_moved_away(svn_wc__db_wcroot_t *wcr
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while(have_row)
{
- svn_sqlite__stmt_t *stmt2;
const char *src_relpath, *dst_relpath;
- int src_op_depth = svn_sqlite__column_int(stmt, 2);
- svn_error_t *err;
- svn_skel_t *conflict;
- svn_depth_t src_depth = depth;
+ int src_op_depth;
+ svn_node_kind_t src_kind;
+ svn_depth_t src_depth;
+ svn_boolean_t skip;
svn_pool_clear(iterpool);
src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
dst_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
+ src_op_depth = svn_sqlite__column_int(stmt, 2);
+ src_kind = svn_sqlite__column_token(stmt, 3, kind_map);
- if (depth != svn_depth_infinity)
- {
- svn_boolean_t skip_this_src = FALSE;
- svn_node_kind_t src_kind;
-
- if (strcmp(src_relpath, local_relpath))
- {
- switch (depth)
- {
- case svn_depth_empty:
- skip_this_src = TRUE;
- break;
- case svn_depth_files:
- src_kind = svn_sqlite__column_token(stmt, 3, kind_map);
- if (src_kind != svn_node_file)
- {
- skip_this_src = TRUE;
- break;
- }
- /* Fallthrough */
- case svn_depth_immediates:
- if (strcmp(svn_relpath_dirname(src_relpath, scratch_pool),
- local_relpath))
- skip_this_src = TRUE;
- src_depth = svn_depth_empty;
- break;
- default:
- SVN_ERR_MALFUNCTION();
- }
- }
+ err = check_bump_layer(&skip, &src_depth, local_relpath, depth,
+ src_relpath, src_kind, iterpool);
- if (skip_this_src)
- {
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- continue;
- }
- }
+ if (err)
+ break;
- err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
- STMT_HAS_LAYER_BETWEEN);
- if (!err)
- err = svn_sqlite__bindf(stmt2, "isdd", wcroot->wc_id, local_relpath,
- op_depth, src_op_depth);
- if (!err)
- err = svn_sqlite__step(&have_row, stmt2);
- if (!err)
- err = svn_sqlite__reset(stmt2);
- if (!err && !have_row)
+ if (!skip)
{
- svn_boolean_t can_bump;
- const char *src_root_relpath = src_relpath;
+ svn_boolean_t recurse;
- if (op_depth == 0)
- err = depth_sufficient_to_bump(&can_bump, src_relpath, wcroot,
- src_depth, scratch_pool);
- else
- /* Having chosen to bump an entire BASE tree move we
- always have sufficient depth to bump subtree moves. */
- can_bump = TRUE;
-
- if (!err)
- {
- if (!can_bump)
- {
- err = bump_mark_tree_conflict(wcroot, src_relpath,
- src_root_relpath, dst_relpath,
- db, scratch_pool);
- if (err)
- return svn_error_compose_create(err,
- svn_sqlite__reset(stmt));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- continue;
- }
-
- while (relpath_depth(src_root_relpath) > src_op_depth)
- src_root_relpath = svn_relpath_dirname(src_root_relpath,
- iterpool);
-
- if (!svn_hash_gets(src_done, src_relpath))
- {
- svn_hash_sets(src_done,
- apr_pstrdup(result_pool, src_relpath), "");
- err = svn_wc__db_read_conflict_internal(&conflict, wcroot,
- src_root_relpath,
- iterpool, iterpool);
- /* ### TODO: check this is the right sort of tree-conflict? */
- if (!err && !conflict)
- {
- /* ### TODO: verify moved_here? */
- err = replace_moved_layer(src_relpath, dst_relpath,
- op_depth, wcroot, iterpool);
-
- if (!err)
- err = bump_moved_away(wcroot, dst_relpath,
- relpath_depth(dst_relpath),
- src_done, depth, db,
- result_pool, iterpool);
- }
- }
- }
+ err = bump_moved_layer(&recurse, wcroot,
+ local_relpath, op_depth,
+ src_relpath, src_op_depth, src_kind, src_depth,
+ dst_relpath,
+ src_done, db, result_pool, iterpool);
+
+ if (!err && recurse)
+ err = bump_moved_away(wcroot, dst_relpath, relpath_depth(dst_relpath),
+ src_done, depth, db, result_pool, iterpool);
}
if (err)
- return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+ break;
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
- SVN_ERR(svn_sqlite__reset(stmt));
+
+ err = svn_error_compose_create(err, svn_sqlite__reset(stmt));
svn_pool_destroy(iterpool);
- return SVN_NO_ERROR;
+ return svn_error_trace(err);
}
svn_error_t *
@@ -2324,7 +2323,6 @@ resolve_delete_raise_moved_away(svn_wc__
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
- int op_depth = relpath_depth(local_relpath);
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
@@ -2333,26 +2331,31 @@ resolve_delete_raise_moved_away(svn_wc__
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_OP_DEPTH_MOVED_PAIR));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
- op_depth));
+ relpath_depth(local_relpath)));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while(have_row)
{
- const char *moved_relpath = svn_sqlite__column_text(stmt, 0, NULL);
- const char *move_root_dst_relpath = svn_sqlite__column_text(stmt, 1,
- NULL);
- const char *moved_dst_repos_relpath = svn_sqlite__column_text(stmt, 2,
- NULL);
+ svn_error_t *err;
+ const char *src_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+ svn_node_kind_t src_kind = svn_sqlite__column_token(stmt, 1, kind_map);
+ const char *dst_relpath = svn_sqlite__column_text(stmt, 2, NULL);
+ const char *src_repos_relpath = svn_sqlite__column_text(stmt, 3, NULL);
svn_pool_clear(iterpool);
- SVN_ERR(mark_tree_conflict(moved_relpath,
- wcroot, db, old_version, new_version,
- move_root_dst_relpath, operation,
- svn_node_dir /* ### ? */,
- svn_node_dir /* ### ? */,
- moved_dst_repos_relpath,
- svn_wc_conflict_reason_moved_away,
- action, local_relpath,
- iterpool));
+ SVN_ERR_ASSERT(src_repos_relpath != NULL);
+
+ err = mark_tree_conflict(src_relpath,
+ wcroot, db, old_version, new_version,
+ dst_relpath, operation,
+ src_kind /* ### old kind */,
+ src_kind /* ### new kind */,
+ src_repos_relpath,
+ svn_wc_conflict_reason_moved_away,
+ action, local_relpath,
+ iterpool);
+
+ if (err)
+ return svn_error_compose_create(err, svn_sqlite__reset(stmt));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
@@ -2411,7 +2414,6 @@ break_move(svn_wc__db_wcroot_t *wcroot,
const char *src_relpath,
int src_op_depth,
const char *dst_relpath,
- int dst_op_depth,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
@@ -2422,11 +2424,12 @@ break_move(svn_wc__db_wcroot_t *wcroot,
src_op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
- /* This statement clears moved_here. */
+ /* The destination is always an op-root, so we can calculate the depth
+ from there. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_UPDATE_OP_DEPTH_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id,
- dst_relpath, dst_op_depth, dst_op_depth));
+ STMT_CLEAR_MOVED_HERE_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ dst_relpath, relpath_depth(dst_relpath)));
SVN_ERR(svn_sqlite__step_done(stmt));
return SVN_NO_ERROR;
@@ -2455,7 +2458,6 @@ svn_wc__db_resolve_break_moved_away_inte
SVN_ERR(break_move(wcroot, local_relpath,
relpath_depth(move_src_op_root_relpath),
move_dst_op_root_relpath,
- relpath_depth(move_dst_op_root_relpath),
scratch_pool));
return SVN_NO_ERROR;
@@ -2474,8 +2476,9 @@ break_moved_away_children_internal(svn_w
STMT_CREATE_UPDATE_MOVE_LIST));
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_MOVED_PAIR2));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ STMT_SELECT_MOVED_DESCENDANTS));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+ relpath_depth(local_relpath)));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
iterpool = svn_pool_create(scratch_pool);
@@ -2488,7 +2491,7 @@ break_moved_away_children_internal(svn_w
svn_pool_clear(iterpool);
SVN_ERR(break_move(wcroot, src_relpath, src_op_depth, dst_relpath,
- relpath_depth(dst_relpath), iterpool));
+ iterpool));
SVN_ERR(update_move_list_add(wcroot, src_relpath,
svn_wc_notify_move_broken,
svn_node_unknown,
Modified: subversion/branches/log-addressing/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/mod_authz_svn/mod_authz_svn.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/log-addressing/subversion/mod_authz_svn/mod_authz_svn.c Wed Nov 27 08:19:45 2013
@@ -91,7 +91,8 @@ create_authz_svn_dir_config(apr_pool_t *
/* canonicalize ACCESS_FILE based on the type of argument.
* If SERVER_RELATIVE is true, ACCESS_FILE is a relative
* path then ACCESS_FILE is converted to an absolute
- * path rooted at the server root. */
+ * path rooted at the server root.
+ * Returns NULL if path is not valid.*/
static const char *
canonicalize_access_file(const char *access_file,
svn_boolean_t server_relative,
@@ -104,7 +105,11 @@ canonicalize_access_file(const char *acc
else if (!svn_path_is_repos_relative_url(access_file))
{
if (server_relative)
- access_file = ap_server_root_relative(pool, access_file);
+ {
+ access_file = ap_server_root_relative(pool, access_file);
+ if (access_file == NULL)
+ return NULL;
+ }
access_file = svn_dirent_internal_style(access_file, pool);
}
@@ -126,6 +131,8 @@ AuthzSVNAccessFile_cmd(cmd_parms *cmd, v
"directives are mutually exclusive.";
conf->access_file = canonicalize_access_file(arg1, TRUE, cmd->pool);
+ if (!conf->access_file)
+ return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, SVN_VA_NULL);
return NULL;
}
@@ -145,6 +152,9 @@ AuthzSVNReposRelativeAccessFile_cmd(cmd_
conf->repo_relative_access_file = canonicalize_access_file(arg1, FALSE,
cmd->pool);
+ if (!conf->repo_relative_access_file)
+ return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, SVN_VA_NULL);
+
return NULL;
}
@@ -155,6 +165,9 @@ AuthzSVNGroupsFile_cmd(cmd_parms *cmd, v
conf->groups_file = canonicalize_access_file(arg1, TRUE, cmd->pool);
+ if (!conf->groups_file)
+ return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, SVN_VA_NULL);
+
return NULL;
}
Modified: subversion/branches/log-addressing/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/mod_dav_svn/dav_svn.h?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/log-addressing/subversion/mod_dav_svn/dav_svn.h Wed Nov 27 08:19:45 2013
@@ -900,6 +900,12 @@ dav_svn__simple_parse_uri(dav_svn__uri_i
const char *uri,
apr_pool_t *pool);
+/* Test the request R to determine if we should return the list of
+ * repositories at the parent path. Only true if SVNListParentPath directive
+ * is 'on' and the request is for our configured root path. */
+svn_boolean_t
+dav_svn__is_parentpath_list(request_rec *r);
+
int dav_svn__find_ns(const apr_array_header_t *namespaces, const char *uri);
Modified: subversion/branches/log-addressing/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/mod_dav_svn/mod_dav_svn.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/log-addressing/subversion/mod_dav_svn/mod_dav_svn.c Wed Nov 27 08:19:45 2013
@@ -1095,30 +1095,77 @@ static int dav_svn__handler(request_rec
#define NO_MAP_TO_STORAGE_NOTE "dav_svn-no-map-to-storage"
-/* Prevent filename on the request from being set since we aren't serving a
- * file off the disk. This means that <Directory> blocks will not match and
- * that * %f in logging formats will show as "-". */
+/* Fill the filename on the request with a bogus path since we aren't serving
+ * a file off the disk. This means that <Directory> blocks will not match and
+ * %f in logging formats will show as "dav_svn:/path/to/repo/path/in/repo".
+ */
static int dav_svn__translate_name(request_rec *r)
{
+ const char *fs_path, *repos_basename, *repos_path;
+ const char *ignore_cleaned_uri, *ignore_relative_path;
+ int ignore_had_slash;
dir_conf_t *conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
/* module is not configured, bail out early */
if (!conf->fs_path && !conf->fs_parent_path)
return DECLINED;
- /* Be paranoid and set it to NULL just in case some other module set it
- * before we got called. */
- r->filename = NULL;
+ if (dav_svn__is_parentpath_list(r))
+ {
+ /* SVNListParentPath is on and the request is for the conf->root_dir,
+ * so just set the repos_basename to an empty string and the repos_path
+ * to NULL so we end up just reporting our parent path as the bogus
+ * path. */
+ repos_basename = "";
+ repos_path = NULL;
+ }
+ else
+ {
+ /* Retrieve path to repo and within repo for the request */
+ dav_error *err = dav_svn_split_uri(r, r->uri, conf->root_dir,
+ &ignore_cleaned_uri,
+ &ignore_had_slash, &repos_basename,
+ &ignore_relative_path, &repos_path);
+ if (err)
+ {
+ dav_svn__log_err(r, err, APLOG_ERR);
+ return err->status;
+ }
+ }
+
+ if (conf->fs_parent_path)
+ {
+ fs_path = svn_dirent_join(conf->fs_parent_path, repos_basename,
+ r->pool);
+ }
+ else
+ {
+ fs_path = conf->fs_path;
+ }
+
+ /* Avoid a trailing slash on the bogus path when repos_path is just "/" */
+ if (repos_path && '/' == repos_path[0] && '\0' == repos_path[1])
+ repos_path = NULL;
+
+ /* Combine 'dav_svn:', fs_path and repos_path to produce the bogus path we're
+ * placing in r->filename. We can't use our standard join helpers such
+ * as svn_dirent_join. fs_path is a dirent and repos_path is a fspath
+ * (that can be trivially converted to a relpath by skipping the leading
+ * slash). In general it is safe to join these, but when a path in a
+ * repository is 'trunk/c:hi' this results in a non canonical dirent on
+ * Windows. Instead we just cat them together. */
+ r->filename = apr_pstrcat(r->pool,
+ "dav_svn:", fs_path, repos_path, SVN_VA_NULL);
- /* Leave a note to ourselves so that we know not to decline in the
+ /* Leave a note to ourselves so that we know not to decline in the
* map_to_storage hook. */
- apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, (const char*)1);
+ apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, (const char*)1);
return OK;
}
/* Prevent core_map_to_storage from running if we prevented the r->filename
* from being set since core_map_to_storage doesn't like r->filename being
- * NULL. */
+ * bogus. */
static int dav_svn__map_to_storage(request_rec *r)
{
/* Check a note we left in translate_name since map_to_storage doesn't
Modified: subversion/branches/log-addressing/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/mod_dav_svn/reports/update.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/log-addressing/subversion/mod_dav_svn/reports/update.c Wed Nov 27 08:19:45 2013
@@ -934,7 +934,7 @@ validate_input_revision(svn_revnum_t rev
const dav_resource *resource)
{
if (! SVN_IS_VALID_REVNUM(revision))
- return SVN_NO_ERROR;
+ return NULL;
if (revision > youngest)
{
@@ -958,7 +958,7 @@ validate_input_revision(svn_revnum_t rev
"Invalid revision found in update report "
"request.", resource->pool);
}
- return SVN_NO_ERROR;
+ return NULL;
}
Modified: subversion/branches/log-addressing/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/mod_dav_svn/repos.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/log-addressing/subversion/mod_dav_svn/repos.c Wed Nov 27 08:19:45 2013
@@ -1348,7 +1348,7 @@ dav_svn_split_uri(request_rec *r,
if (ch == '\0')
{
/* relative is just "!svn", which is malformed. */
- return dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+ return dav_svn__new_error(r->pool, HTTP_NOT_FOUND,
SVN_ERR_APMOD_MALFORMED_URI,
"Nothing follows the svn special_uri.");
}
@@ -1375,7 +1375,7 @@ dav_svn_split_uri(request_rec *r,
*repos_path = NULL;
else
return dav_svn__new_error(
- r->pool, HTTP_INTERNAL_SERVER_ERROR,
+ r->pool, HTTP_NOT_FOUND,
SVN_ERR_APMOD_MALFORMED_URI,
"Missing info after special_uri.");
}
@@ -1399,7 +1399,7 @@ dav_svn_split_uri(request_rec *r,
/* Did we break from the loop prematurely? */
if (j != (defn->numcomponents - 1))
return dav_svn__new_error(
- r->pool, HTTP_INTERNAL_SERVER_ERROR,
+ r->pool, HTTP_NOT_FOUND,
SVN_ERR_APMOD_MALFORMED_URI,
"Not enough components after "
"special_uri.");
@@ -1413,13 +1413,13 @@ dav_svn_split_uri(request_rec *r,
else
{
/* Found a slash after the special components. */
- *repos_path = apr_pstrdup(r->pool, start);
+ *repos_path = apr_pstrdup(r->pool, start - 1);
}
}
else
{
return
- dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+ dav_svn__new_error(r->pool, HTTP_NOT_FOUND,
SVN_ERR_APMOD_MALFORMED_URI,
"Unknown data after special_uri.");
}
@@ -1430,7 +1430,7 @@ dav_svn_split_uri(request_rec *r,
if (defn->name == NULL)
return
- dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+ dav_svn__new_error(r->pool, HTTP_NOT_FOUND,
SVN_ERR_APMOD_MALFORMED_URI,
"Couldn't match subdir after special_uri.");
}
@@ -1439,7 +1439,7 @@ dav_svn_split_uri(request_rec *r,
{
/* There's no "!svn/" at all, so the relative path is already
a valid path within the repository. */
- *repos_path = apr_pstrdup(r->pool, relative);
+ *repos_path = apr_pstrdup(r->pool, relative - 1);
}
}
@@ -1970,26 +1970,12 @@ get_resource(request_rec *r,
/* Special case: detect and build the SVNParentPath as a unique type
of private resource, iff the SVNListParentPath directive is 'on'. */
- if (fs_parent_path && dav_svn__get_list_parentpath_flag(r))
+ if (dav_svn__is_parentpath_list(r))
{
- char *uri = apr_pstrdup(r->pool, r->uri);
- char *parentpath = apr_pstrdup(r->pool, root_path);
- apr_size_t uri_len = strlen(uri);
- apr_size_t parentpath_len = strlen(parentpath);
-
- if (uri[uri_len-1] == '/')
- uri[uri_len-1] = '\0';
-
- if (parentpath[parentpath_len-1] == '/')
- parentpath[parentpath_len-1] = '\0';
-
- if (strcmp(parentpath, uri) == 0)
- {
- err = get_parentpath_resource(r, resource);
- if (err)
- return err;
- return NULL;
- }
+ err = get_parentpath_resource(r, resource);
+ if (err)
+ return err;
+ return NULL;
}
/* This does all the work of interpreting/splitting the request uri. */
@@ -2173,7 +2159,7 @@ get_resource(request_rec *r,
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
dav_svn__get_fulltext_cache_flag(r) ? "1" :"0");
svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
- dav_svn__get_revprop_cache_flag(r) ? "1" :"0");
+ dav_svn__get_revprop_cache_flag(r) ? "2" :"0");
/* Disallow BDB/event until issue 4157 is fixed. */
if (!strcmp(ap_show_mpm(), "event"))
@@ -2205,9 +2191,16 @@ get_resource(request_rec *r,
leak that path back to the client, because that would be
a security risk, but we do want to log the real error on
the server side. */
- return dav_svn__sanitize_error(serr, "Could not open the requested "
- "SVN filesystem",
- HTTP_INTERNAL_SERVER_ERROR, r);
+
+ apr_status_t cause = svn_error_root_cause(serr)->apr_err;
+ if (APR_STATUS_IS_ENOENT(cause) || APR_STATUS_IS_ENOTDIR(cause))
+ return dav_svn__sanitize_error(
+ serr, "Could not find the requested SVN filesystem",
+ HTTP_NOT_FOUND, r);
+ else
+ return dav_svn__sanitize_error(
+ serr, "Could not open the requested SVN filesystem",
+ HTTP_INTERNAL_SERVER_ERROR, r);
}
/* Cache the open repos for the next request on this connection */
@@ -2456,9 +2449,12 @@ get_parent_resource(const dav_resource *
parent->info = parentinfo;
parentinfo->uri_path =
- svn_stringbuf_create(get_parent_path(resource->info->uri_path->data,
- TRUE, resource->pool),
- resource->pool);
+ svn_stringbuf_create(
+ get_parent_path(
+ svn_urlpath__canonicalize(resource->info->uri_path->data,
+ resource->pool),
+ TRUE, resource->pool),
+ resource->pool);
parentinfo->repos = resource->info->repos;
parentinfo->root = resource->info->root;
parentinfo->r = resource->info->r;
@@ -3799,23 +3795,29 @@ copy_resource(const dav_resource *src,
return err;
}
- serr = svn_dirent_get_absolute(&src_repos_path,
- svn_repos_path(src->info->repos->repos,
- src->pool),
- src->pool);
- if (!serr)
- serr = svn_dirent_get_absolute(&dst_repos_path,
- svn_repos_path(dst->info->repos->repos,
- dst->pool),
- dst->pool);
+ src_repos_path = svn_repos_path(src->info->repos->repos, src->pool);
+ dst_repos_path = svn_repos_path(dst->info->repos->repos, dst->pool);
+
+ if (strcmp(src_repos_path, dst_repos_path) != 0)
+ {
+ /* Perhaps the source and dst repos use different path formats? */
+ serr = svn_error_compose_create(
+ svn_dirent_get_absolute(&src_repos_path, src_repos_path,
+ src->pool),
+ svn_dirent_get_absolute(&dst_repos_path, dst_repos_path,
+ dst->pool));
+
+ if (!serr && (strcmp(src_repos_path, dst_repos_path) != 0))
+ return dav_svn__new_error_tag(
+ dst->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Copy source and destination are in different repositories.",
+ SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG);
+ }
+ else
+ serr = SVN_NO_ERROR;
if (!serr)
{
- if (strcmp(src_repos_path, dst_repos_path) != 0)
- return dav_svn__new_error_tag
- (dst->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Copy source and destination are in different repositories.",
- SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG);
serr = svn_fs_copy(src->info->root.root, /* root object of src rev*/
src->info->repos_path, /* relative path of src */
dst->info->root.root, /* root object of dst txn*/
Modified: subversion/branches/log-addressing/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/mod_dav_svn/util.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/log-addressing/subversion/mod_dav_svn/util.c Wed Nov 27 08:19:45 2013
@@ -425,6 +425,32 @@ dav_svn__simple_parse_uri(dav_svn__uri_i
"Unsupported URI form");
}
+svn_boolean_t
+dav_svn__is_parentpath_list(request_rec *r)
+{
+ const char *fs_parent_path = dav_svn__get_fs_parent_path(r);
+
+ if (fs_parent_path && dav_svn__get_list_parentpath_flag(r))
+ {
+ const char *root_path = dav_svn__get_root_dir(r);
+ char *uri = apr_pstrdup(r->pool, r->uri);
+ char *parentpath = apr_pstrdup(r->pool, root_path);
+ apr_size_t uri_len = strlen(uri);
+ apr_size_t parentpath_len = strlen(parentpath);
+
+ if (uri[uri_len-1] == '/')
+ uri[uri_len-1] = '\0';
+
+ if (parentpath[parentpath_len-1] == '/')
+ parentpath[parentpath_len-1] = '\0';
+
+ if (strcmp(parentpath, uri) == 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
/* ### move this into apr_xml */
int
Modified: subversion/branches/log-addressing/subversion/svn/add-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/add-cmd.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/add-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/add-cmd.c Wed Nov 27 08:19:45 2013
@@ -83,7 +83,7 @@ svn_cl__add(apr_getopt_t *os,
errors, opt_state->quiet,
SVN_ERR_ENTRY_EXISTS,
SVN_ERR_WC_PATH_NOT_FOUND,
- SVN_NO_ERROR));
+ 0));
}
svn_pool_destroy(iterpool);
Modified: subversion/branches/log-addressing/subversion/svn/blame-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/blame-cmd.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/blame-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/blame-cmd.c Wed Nov 27 08:19:45 2013
@@ -74,7 +74,7 @@ blame_receiver_xml(void *baton,
"line-number",
apr_psprintf(pool, "%" APR_INT64_T_FMT,
line_no + 1),
- NULL);
+ SVN_VA_NULL);
if (SVN_IS_VALID_REVNUM(revision))
svn_cl__print_xml_commit(&sb, revision,
@@ -88,7 +88,7 @@ blame_receiver_xml(void *baton,
{
/* "<merged>" */
svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "merged",
- "path", merged_path, NULL);
+ "path", merged_path, SVN_VA_NULL);
svn_cl__print_xml_commit(&sb, merged_revision,
svn_prop_get_value(merged_rev_props,
@@ -350,7 +350,7 @@ svn_cl__blame(apr_getopt_t *os,
if (! svn_path_is_url(target))
outpath = svn_dirent_local_style(truepath, subpool);
svn_xml_make_open_tag(&bl.sbuf, pool, svn_xml_normal, "target",
- "path", outpath, NULL);
+ "path", outpath, SVN_VA_NULL);
receiver = blame_receiver_xml;
}
Modified: subversion/branches/log-addressing/subversion/svn/cat-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/cat-cmd.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/cat-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/cat-cmd.c Wed Nov 27 08:19:45 2013
@@ -84,7 +84,7 @@ svn_cl__cat(apr_getopt_t *os,
SVN_ERR_ENTRY_NOT_FOUND,
SVN_ERR_CLIENT_IS_DIRECTORY,
SVN_ERR_FS_NOT_FOUND,
- SVN_NO_ERROR));
+ 0));
}
svn_pool_destroy(subpool);
Modified: subversion/branches/log-addressing/subversion/svn/changelist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/changelist-cmd.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/changelist-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/changelist-cmd.c Wed Nov 27 08:19:45 2013
@@ -106,7 +106,7 @@ svn_cl__changelist(apr_getopt_t *os,
errors, opt_state->quiet,
SVN_ERR_UNVERSIONED_RESOURCE,
SVN_ERR_WC_PATH_NOT_FOUND,
- SVN_NO_ERROR));
+ 0));
}
else
{
@@ -117,7 +117,7 @@ svn_cl__changelist(apr_getopt_t *os,
errors, opt_state->quiet,
SVN_ERR_UNVERSIONED_RESOURCE,
SVN_ERR_WC_PATH_NOT_FOUND,
- SVN_NO_ERROR));
+ 0));
}
if (errors->nelts > 0)
Modified: subversion/branches/log-addressing/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/cl.h?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/cl.h (original)
+++ subversion/branches/log-addressing/subversion/svn/cl.h Wed Nov 27 08:19:45 2013
@@ -320,7 +320,7 @@ extern const apr_getopt_option_t svn_cl_
*
* Typically, error codes like SVN_ERR_UNVERSIONED_RESOURCE,
* SVN_ERR_ENTRY_NOT_FOUND, etc, are supplied in varargs. Don't
- * forget to terminate the argument list with SVN_NO_ERROR.
+ * forget to terminate the argument list with 0 (or APR_SUCCESS).
*/
svn_error_t *
svn_cl__try(svn_error_t *err,
Modified: subversion/branches/log-addressing/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/diff-cmd.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/diff-cmd.c Wed Nov 27 08:19:45 2013
@@ -117,7 +117,7 @@ summarize_xml(const svn_client_diff_summ
"kind", svn_cl__node_kind_str_xml(summary->node_kind),
"item", kind_to_word(summary->summarize_kind),
"props", summary->prop_changed ? "modified" : "none",
- NULL);
+ SVN_VA_NULL);
svn_xml_escape_cdata_cstring(&sb, path, pool);
svn_xml_make_close_tag(&sb, pool, "path");
@@ -212,7 +212,7 @@ svn_cl__diff(apr_getopt_t *os,
SVN_ERR(svn_cl__xml_print_header("diff", pool));
sb = svn_stringbuf_create_empty(pool);
- svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "paths", NULL);
+ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "paths", SVN_VA_NULL);
SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
}
Modified: subversion/branches/log-addressing/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/svn/info-cmd.c?rev=1545958&r1=1545957&r2=1545958&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/svn/info-cmd.c (original)
+++ subversion/branches/log-addressing/subversion/svn/info-cmd.c Wed Nov 27 08:19:45 2013
@@ -100,7 +100,7 @@ print_info_xml(void *baton,
path_prefix, target, pool),
"kind", svn_cl__node_kind_str_xml(info->kind),
"revision", rev_str,
- NULL);
+ SVN_VA_NULL);
/* "<url> xx </url>" */
svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL);
@@ -121,7 +121,8 @@ print_info_xml(void *baton,
if (info->repos_root_URL || info->repos_UUID)
{
/* "<repository>" */
- svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "repository", NULL);
+ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "repository",
+ SVN_VA_NULL);
/* "<root> xx </root>" */
svn_cl__xml_tagged_cdata(&sb, pool, "root", info->repos_root_URL);
@@ -136,7 +137,8 @@ print_info_xml(void *baton,
if (info->wc_info)
{
/* "<wc-info>" */
- svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "wc-info", NULL);
+ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "wc-info",
+ SVN_VA_NULL);
/* "<wcroot-abspath> xx </wcroot-abspath>" */
if (info->wc_info->wcroot_abspath)