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 12:52:46 UTC
svn commit: r1546002 [23/39] - in /subversion/branches/verify-keep-going: ./
build/ build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/win32/ contrib/client-side/emacs/
contrib/server-side/ contrib/server-side/svnc...
Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_private.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_private.h Wed Nov 27 11:52:35 2013
@@ -42,7 +42,8 @@ struct svn_wc__db_t {
opened, and found to be not-current? */
svn_boolean_t verify_format;
- /* Should we ensure the WORK_QUEUE is empty when a WCROOT is opened? */
+ /* Should we ensure the WORK_QUEUE is empty when a DB is locked
+ * for writing? */
svn_boolean_t enforce_empty_wq;
/* Should we open Sqlite databases EXCLUSIVE */
@@ -122,7 +123,6 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
apr_int64_t wc_id,
int format,
svn_boolean_t verify_format,
- svn_boolean_t enforce_empty_wq,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -145,6 +145,9 @@ svn_wc__db_wcroot_parse_local_abspath(sv
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Return an error if the work queue in SDB is non-empty. */
+svn_error_t *
+svn_wc__db_verify_no_work(svn_sqlite__db_t *sdb);
/* Assert that the given WCROOT is usable.
NOTE: the expression is multiply-evaluated!! */
@@ -358,6 +361,18 @@ svn_wc__db_with_txn(svn_wc__db_wcroot_t
SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb)
+/* Evaluate the expressions EXPR1..EXPR4 within a transaction, returning the
+ * first error if an error occurs.
+ *
+ * Begin a transaction in WCROOT's DB; evaluate the expressions, which would
+ * typically be function calls that do some work in DB; finally commit
+ * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
+ * the transaction.
+ */
+#define SVN_WC__DB_WITH_TXN4(expr1, expr2, expr3, expr4, wcroot) \
+ SVN_SQLITE__WITH_LOCK4(expr1, expr2, expr3, expr4, (wcroot)->sdb)
+
+
/* Return CHILDREN mapping const char * names to svn_node_kind_t * for the
children of LOCAL_RELPATH at OP_DEPTH. */
svn_error_t *
@@ -420,6 +435,38 @@ svn_wc__db_retract_parent_delete(svn_wc_
int op_depth,
apr_pool_t *scratch_pool);
+/* Extract the moved-to information for LOCAL_RELPATH at OP-DEPTH by
+ examining the lowest working node above OP_DEPTH. The output paths
+ are NULL if there is no move, otherwise:
+
+ *MOVE_DST_RELPATH: the moved-to destination of LOCAL_RELPATH.
+
+ *MOVE_DST_OP_ROOT_RELPATH: the moved-to destination of the root of
+ the move of LOCAL_RELPATH. This may be equal to *MOVE_DST_RELPATH
+ if LOCAL_RELPATH is the root of the move.
+
+ *MOVE_SRC_ROOT_RELPATH: the root of the move source. For moves
+ inside a delete this will be different from *MOVE_SRC_OP_ROOT_RELPATH.
+
+ *MOVE_SRC_OP_ROOT_RELPATH: the root of the source layer that
+ contains the move. For moves inside deletes this is the root of
+ the delete, for other moves this is the root of the move.
+
+ Given a path A/B/C with A/B moved to X then for A/B/C
+
+ MOVE_DST_RELPATH is X/C
+ MOVE_DST_OP_ROOT_RELPATH is X
+ MOVE_SRC_ROOT_RELPATH is A/B
+ MOVE_SRC_OP_ROOT_RELPATH is A/B
+
+ If A is then deleted the MOVE_DST_RELPATH, MOVE_DST_OP_ROOT_RELPATH
+ and MOVE_SRC_ROOT_RELPATH remain the same but MOVE_SRC_OP_ROOT_RELPATH
+ changes to A.
+
+ ### Think about combining with scan_deletion? Also with
+ ### scan_addition to get moved-to for replaces? Do we need to
+ ### return the op-root of the move source, i.e. A/B in the example
+ ### above? */
svn_error_t *
svn_wc__db_op_depth_moved_to(const char **move_dst_relpath,
const char **move_dst_op_root_relpath,
@@ -431,6 +478,23 @@ svn_wc__db_op_depth_moved_to(const char
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Like svn_wc__db_op_set_props, but updates ACTUAL_NODE directly without
+ comparing with the pristine properties, etc.
+*/
+svn_error_t *
+svn_wc__db_op_set_props_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_hash_t *props,
+ svn_boolean_t clear_recorded_info,
+ apr_pool_t *scratch_pool);
+
+svn_error_t *
+svn_wc__db_read_props_internal(apr_hash_t **props,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Do a post-drive revision bump for the moved-away destination for
any move sources under LOCAL_RELPATH. This is called from within
the revision bump transaction after the tree at LOCAL_RELPATH has
@@ -442,9 +506,12 @@ svn_wc__db_bump_moved_away(svn_wc__db_wc
svn_wc__db_t *db,
apr_pool_t *scratch_pool);
+/* Unbreak the move from LOCAL_RELPATH on op-depth in WCROOT, by making
+ the destination a normal copy */
svn_error_t *
svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ int op_depth,
apr_pool_t *scratch_pool);
svn_error_t *
Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_update_move.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_update_move.c Wed Nov 27 11:52:35 2013
@@ -78,6 +78,7 @@
#include <assert.h>
+#include "svn_private_config.h"
#include "svn_checksum.h"
#include "svn_dirent_uri.h"
#include "svn_error.h"
@@ -90,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"
@@ -113,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;
@@ -126,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
@@ -250,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);
@@ -302,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));
@@ -365,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
@@ -373,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,
@@ -451,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;
@@ -471,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,
@@ -498,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 */
@@ -542,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;
@@ -562,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,
@@ -588,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 */
@@ -629,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
{
@@ -720,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,
@@ -736,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;
@@ -786,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,
@@ -796,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,
@@ -815,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;
@@ -834,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));
@@ -883,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;
@@ -904,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));
@@ -914,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? */,
@@ -939,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,
@@ -976,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,
@@ -1005,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;
@@ -1029,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,
@@ -1045,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;
@@ -1058,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));
}
@@ -1068,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
@@ -1114,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;
+ /* 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));
- 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));
-
- 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)
@@ -1228,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
@@ -1273,68 +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_rotate(void *baton,
- const apr_array_header_t *relpaths,
- const apr_array_header_t *revisions,
- 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_rotate,
- tc_editor_complete,
- tc_editor_abort
-};
-
/*
* Driver code.
@@ -1416,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,
@@ -1433,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);
@@ -1516,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;
@@ -1543,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)
@@ -1578,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)
{
@@ -1601,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));
}
}
@@ -1617,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)
@@ -1650,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;
@@ -1719,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
@@ -1729,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,
@@ -1760,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;
}
@@ -1788,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));
@@ -1858,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;
@@ -1869,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(
@@ -1883,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));
@@ -1918,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));
@@ -2017,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)
{
@@ -2038,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();
@@ -2124,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,
@@ -2141,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);
@@ -2151,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;
-
- 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;
+ svn_boolean_t recurse;
- 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 *
@@ -2284,30 +2274,34 @@ svn_wc__db_bump_moved_away(svn_wc__db_wc
svn_wc__db_t *db,
apr_pool_t *scratch_pool)
{
- const char *dummy1, *move_dst_op_root_relpath;
- const char *move_src_root_relpath, *move_src_op_root_relpath;
apr_hash_t *src_done;
SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
STMT_CREATE_UPDATE_MOVE_LIST));
- SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath,
- &move_src_root_relpath,
- &move_src_op_root_relpath, 0,
- wcroot, local_relpath,
- scratch_pool, scratch_pool));
-
- if (move_src_root_relpath)
+ if (local_relpath[0] != '\0')
{
- if (strcmp(move_src_root_relpath, local_relpath))
+ const char *dummy1, *move_dst_op_root_relpath;
+ const char *move_src_root_relpath, *move_src_op_root_relpath;
+
+ /* Is the root of the update moved away? (Impossible for the wcroot) */
+ SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath,
+ &move_src_root_relpath,
+ &move_src_op_root_relpath, 0,
+ wcroot, local_relpath,
+ scratch_pool, scratch_pool));
+
+ if (move_src_root_relpath)
{
- SVN_ERR(bump_mark_tree_conflict(wcroot, move_src_root_relpath,
- move_src_op_root_relpath,
- move_dst_op_root_relpath,
- db, scratch_pool));
- return SVN_NO_ERROR;
+ if (strcmp(move_src_root_relpath, local_relpath))
+ {
+ SVN_ERR(bump_mark_tree_conflict(wcroot, move_src_root_relpath,
+ move_src_op_root_relpath,
+ move_dst_op_root_relpath,
+ db, scratch_pool));
+ return SVN_NO_ERROR;
+ }
}
-
}
src_done = apr_hash_make(scratch_pool);
@@ -2329,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,
@@ -2338,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));
}
@@ -2416,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;
@@ -2427,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;
@@ -2440,21 +2438,26 @@ break_move(svn_wc__db_wcroot_t *wcroot,
svn_error_t *
svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ int op_depth,
apr_pool_t *scratch_pool)
{
const char *dummy1, *move_dst_op_root_relpath;
const char *dummy2, *move_src_op_root_relpath;
+ /* We want to include the passed op-depth, but the function does a > check */
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,
+ op_depth - 1,
wcroot, local_relpath,
scratch_pool, scratch_pool));
+
+ SVN_ERR_ASSERT(move_src_op_root_relpath != NULL
+ && move_dst_op_root_relpath != NULL);
+
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;
@@ -2473,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);
@@ -2487,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,
@@ -2519,6 +2523,7 @@ svn_wc__db_resolve_break_moved_away(svn_
SVN_WC__DB_WITH_TXN(
svn_wc__db_resolve_break_moved_away_internal(wcroot, local_relpath,
+ relpath_depth(local_relpath),
scratch_pool),
wcroot);
Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_wcroot.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/wc_db_wcroot.c Wed Nov 27 11:52:35 2013
@@ -25,6 +25,7 @@
#include <assert.h>
+#include "svn_private_config.h"
#include "svn_dirent_uri.h"
#include "svn_hash.h"
#include "svn_path.h"
@@ -35,8 +36,6 @@
#include "wc_db_private.h"
#include "wc-queries.h"
-#include "svn_private_config.h"
-
/* ### Same values as wc_db.c */
#define SDB_FILE "wc.db"
#define UNKNOWN_WC_ID ((apr_int64_t) -1)
@@ -145,9 +144,8 @@ get_path_kind(svn_node_kind_t *kind,
}
-/* Return an error if the work queue in SDB is non-empty. */
-static svn_error_t *
-verify_no_work(svn_sqlite__db_t *sdb)
+svn_error_t *
+svn_wc__db_verify_no_work(svn_sqlite__db_t *sdb)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
@@ -258,7 +256,6 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
apr_int64_t wc_id,
int format,
svn_boolean_t verify_format,
- svn_boolean_t enforce_empty_wq,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -293,11 +290,11 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
}
/* Verify that no work items exists. If they do, then our integrity is
- suspect and, thus, we cannot use this database. */
- if (format >= SVN_WC__HAS_WORK_QUEUE
- && (enforce_empty_wq || (format < SVN_WC__VERSION && verify_format)))
+ suspect and, thus, we cannot upgrade this database. */
+ if (format >= SVN_WC__HAS_WORK_QUEUE &&
+ format < SVN_WC__VERSION && verify_format)
{
- svn_error_t *err = verify_no_work(sdb);
+ svn_error_t *err = svn_wc__db_verify_no_work(sdb);
if (err)
{
/* Special message for attempts to upgrade a 1.7-dev wc with
@@ -678,7 +675,7 @@ try_symlink_as_dir:
? symlink_wcroot_abspath
: local_abspath),
sdb, wc_id, FORMAT_FROM_SDB,
- db->verify_format, db->enforce_empty_wq,
+ db->verify_format,
db->state_pool, scratch_pool);
if (err && (err->apr_err == SVN_ERR_WC_UNSUPPORTED_FORMAT ||
err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED) &&
@@ -749,7 +746,7 @@ try_symlink_as_dir:
? symlink_wcroot_abspath
: local_abspath),
NULL, UNKNOWN_WC_ID, wc_format,
- db->verify_format, db->enforce_empty_wq,
+ db->verify_format,
db->state_pool, scratch_pool));
}
Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/workqueue.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/workqueue.c Wed Nov 27 11:52:35 2013
@@ -23,6 +23,7 @@
#include <apr_pools.h>
+#include "svn_private_config.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_dirent_uri.h"
@@ -37,7 +38,6 @@
#include "conflicts.h"
#include "translate.h"
-#include "svn_private_config.h"
#include "private/svn_skel.h"
Modified: subversion/branches/verify-keep-going/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/mod_authz_svn/mod_authz_svn.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/verify-keep-going/subversion/mod_authz_svn/mod_authz_svn.c Wed Nov 27 11:52:35 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;
}
@@ -363,7 +376,7 @@ get_access_conf(request_rec *r, authz_sv
{
access_file = svn_dirent_join_many(scratch_pool, repos_path, "conf",
conf->repo_relative_access_file,
- NULL);
+ SVN_VA_NULL);
}
}
else
@@ -404,7 +417,7 @@ get_access_conf(request_rec *r, authz_sv
}
cache_key = apr_pstrcat(scratch_pool, "mod_authz_svn:",
- access_file, groups_file, (char *)NULL);
+ access_file, groups_file, SVN_VA_NULL);
apr_pool_userdata_get(&user_data, cache_key, r->connection->pool);
access_conf = user_data;
if (access_conf == NULL)
@@ -572,7 +585,7 @@ req_check_access(request_rec *r,
repos_path = svn_fspath__canonicalize(repos_path, r->pool);
*repos_path_ref = apr_pstrcat(r->pool, repos_name, ":", repos_path,
- (char *)NULL);
+ SVN_VA_NULL);
if (r->method_number == M_MOVE || r->method_number == M_COPY)
{
@@ -620,7 +633,7 @@ req_check_access(request_rec *r,
dest_repos_path = svn_fspath__canonicalize(dest_repos_path, r->pool);
*dest_repos_path_ref = apr_pstrcat(r->pool, dest_repos_name, ":",
- dest_repos_path, (char *)NULL);
+ dest_repos_path, SVN_VA_NULL);
}
/* Retrieve/cache authorization file */
@@ -806,14 +819,15 @@ access_checker(request_rec *r)
&authz_svn_module);
const char *repos_path = NULL;
const char *dest_repos_path = NULL;
- int status;
+ int status, authn_required;
/* We are not configured to run */
if (!conf->anonymous
|| (! (conf->access_file || conf->repo_relative_access_file)))
return DECLINED;
- if (ap_some_auth_required(r))
+ authn_required = ap_some_auth_required(r);
+ if (authn_required)
{
/* It makes no sense to check if a location is both accessible
* anonymous and by an authenticated user (in the same request!).
@@ -843,7 +857,7 @@ access_checker(request_rec *r)
if (!conf->authoritative)
return DECLINED;
- if (!ap_some_auth_required(r))
+ if (!authn_required)
log_access_verdict(APLOG_MARK, r, 0, repos_path, dest_repos_path);
return HTTP_FORBIDDEN;
Modified: subversion/branches/verify-keep-going/subversion/mod_dav_svn/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/mod_dav_svn/authz.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/mod_dav_svn/authz.c (original)
+++ subversion/branches/verify-keep-going/subversion/mod_dav_svn/authz.c Wed Nov 27 11:52:35 2013
@@ -57,7 +57,7 @@ dav_svn__allow_read(request_rec *r,
/* Sometimes we get paths that do not start with '/' and
hence below uri concatenation would lead to wrong uris .*/
if (path && path[0] != '/')
- path = apr_pstrcat(pool, "/", path, NULL);
+ path = apr_pstrcat(pool, "/", path, SVN_VA_NULL);
/* If bypass is specified and authz has exported the provider.
Otherwise, we fall through to the full version. This should be
Modified: subversion/branches/verify-keep-going/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/mod_dav_svn/dav_svn.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/verify-keep-going/subversion/mod_dav_svn/dav_svn.h Wed Nov 27 11:52:35 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/verify-keep-going/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/mod_dav_svn/lock.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/verify-keep-going/subversion/mod_dav_svn/lock.c Wed Nov 27 11:52:35 2013
@@ -92,7 +92,7 @@ svn_lock_to_dav_lock(dav_lock **dlock,
"<D:owner xmlns:D=\"DAV:\">",
apr_xml_quote_string(pool,
slock->comment, 1),
- "</D:owner>", (char *)NULL);
+ "</D:owner>", SVN_VA_NULL);
}
else
{
@@ -134,7 +134,7 @@ unescape_xml(const char **output,
apr_xml_doc *xml_doc;
apr_status_t apr_err;
const char *xml_input = apr_pstrcat
- (pool, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", input, (char *)NULL);
+ (pool, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", input, SVN_VA_NULL);
apr_err = apr_xml_parser_feed(xml_parser, xml_input, strlen(xml_input));
if (!apr_err)
Modified: subversion/branches/verify-keep-going/subversion/mod_dav_svn/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/mod_dav_svn/merge.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/verify-keep-going/subversion/mod_dav_svn/merge.c Wed Nov 27 11:52:35 2013
@@ -155,6 +155,8 @@ do_resources(const dav_svn_repos *repos,
case svn_fs_path_change_add:
case svn_fs_path_change_replace:
+ case svn_fs_path_change_move:
+ case svn_fs_path_change_movereplace:
send_self = TRUE;
send_parent = TRUE;
break;
Modified: subversion/branches/verify-keep-going/subversion/mod_dav_svn/mirror.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/mod_dav_svn/mirror.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/mod_dav_svn/mirror.c (original)
+++ subversion/branches/verify-keep-going/subversion/mod_dav_svn/mirror.c Wed Nov 27 11:52:35 2013
@@ -56,7 +56,7 @@ static int proxy_request_fixup(request_r
r->filename = (char *) svn_path_uri_encode(apr_pstrcat(r->pool, "proxy:",
master_uri,
uri_segment,
- (char *)NULL),
+ SVN_VA_NULL),
r->pool);
r->handler = "proxy-server";
@@ -102,11 +102,11 @@ int dav_svn__proxy_request_fixup(request
r->method_number == M_GET) {
if ((seg = ap_strstr(r->uri, root_dir))) {
if (ap_strstr_c(seg, apr_pstrcat(r->pool, special_uri,
- "/wrk/", (char *)NULL))
+ "/wrk/", SVN_VA_NULL))
|| ap_strstr_c(seg, apr_pstrcat(r->pool, special_uri,
- "/txn/", (char *)NULL))
+ "/txn/", SVN_VA_NULL))
|| ap_strstr_c(seg, apr_pstrcat(r->pool, special_uri,
- "/txr/", (char *)NULL))) {
+ "/txr/", SVN_VA_NULL))) {
int rv;
seg += strlen(root_dir);
rv = proxy_request_fixup(r, master_uri, seg);
@@ -259,7 +259,7 @@ apr_status_t dav_svn__location_header_fi
new_uri = ap_construct_url(r->pool,
apr_pstrcat(r->pool,
dav_svn__get_root_dir(r), "/",
- start_foo, (char *)NULL),
+ start_foo, SVN_VA_NULL),
r);
apr_table_set(r->headers_out, "Location", new_uri);
}