You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/11/30 11:24:23 UTC
svn commit: r1717223 [34/50] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/
contrib/hook-scripts/ notes/ notes/api-errata/1.9/ notes/move-tracking/
subversion/ subversion/bindings/ctypes-python/...
Modified: subversion/branches/ra-git/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/props.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/props.c Mon Nov 30 10:24:16 2015
@@ -327,7 +327,8 @@ svn_wc_merge_props3(svn_wc_notify_state_
{
svn_boolean_t prop_conflicted;
- SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, conflict_skel,
+ SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, kind,
+ conflict_skel,
NULL /* merge_options */,
conflict_func, conflict_baton,
cancel_func, cancel_baton,
@@ -750,7 +751,8 @@ svn_wc__create_prejfile(const char **tmp
apr_hash_t *conflicted_props;
svn_skel_t *conflicts;
- SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, db, local_abspath,
+ SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
+ db, local_abspath,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL, NULL,
@@ -2168,11 +2170,8 @@ svn_wc_canonicalize_svn_prop(const svn_s
/* Keep this static, it may get stored (for read-only purposes) in a
hash that outlives this function. */
- static const svn_string_t boolean_value =
- {
- SVN_PROP_BOOLEAN_TRUE,
- sizeof(SVN_PROP_BOOLEAN_TRUE) - 1
- };
+ static const svn_string_t boolean_value
+ = SVN__STATIC_STRING(SVN_PROP_BOOLEAN_TRUE);
SVN_ERR(validate_prop_against_node_kind(propname, path, kind, pool));
Modified: subversion/branches/ra-git/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/questions.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/questions.c Mon Nov 30 10:24:16 2015
@@ -369,7 +369,8 @@ internal_conflicted_p(svn_boolean_t *tex
svn_boolean_t resolved_text = FALSE;
svn_boolean_t resolved_props = FALSE;
- SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, db, local_abspath,
+ SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
+ db, local_abspath,
scratch_pool, scratch_pool));
if (!conflicts)
Modified: subversion/branches/ra-git/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/status.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/status.c Mon Nov 30 10:24:16 2015
@@ -69,6 +69,7 @@ typedef struct svn_wc__internal_status_t
svn_wc_status3_t s; /* First member; same pointer*/
svn_boolean_t has_descendants;
+ svn_boolean_t op_root;
/* Make sure to update hash_stash() when adding values here */
} svn_wc__internal_status_t;
@@ -587,7 +588,8 @@ assemble_status(svn_wc__internal_status_
This filter should match the filter in is_sendable_status() */
if (! get_all)
if (((node_status == svn_wc_status_none)
- || (node_status == svn_wc_status_normal))
+ || (node_status == svn_wc_status_normal)
+ || (node_status == svn_wc_status_deleted && !info->op_root))
&& (! switched_p)
&& (! info->locked)
@@ -606,6 +608,7 @@ assemble_status(svn_wc__internal_status_
inner_stat = apr_pcalloc(result_pool, sizeof(*inner_stat));
stat = &inner_stat->s;
inner_stat->has_descendants = info->has_descendants;
+ inner_stat->op_root = info->op_root;
switch (info->kind)
{
@@ -1484,6 +1487,7 @@ hash_stash(void *baton,
/* Copy the internal/private data. */
svn_wc__internal_status_t *is = new_status;
is->has_descendants = old_status->has_descendants;
+ is->op_root = old_status->op_root;
assert(! svn_hash_gets(stat_hash, path));
svn_hash_sets(stat_hash, apr_pstrdup(hash_pool, path), new_status);
@@ -1865,7 +1869,9 @@ is_sendable_status(const svn_wc__interna
/* If the text, property or tree state is interesting, send it. */
if ((status->node_status != svn_wc_status_none)
- && (status->node_status != svn_wc_status_normal))
+ && (status->node_status != svn_wc_status_normal)
+ && !(status->node_status == svn_wc_status_deleted
+ && !i_status->op_root))
return TRUE;
/* If it's switched, send it. */
Modified: subversion/branches/ra-git/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/tree_conflicts.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/tree_conflicts.c Mon Nov 30 10:24:16 2015
@@ -485,8 +485,10 @@ svn_wc__get_tree_conflict(const svn_wc_c
int i;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_wc__read_conflicts(&conflicts,
- wc_ctx->db, local_abspath, FALSE,
+ SVN_ERR(svn_wc__read_conflicts(&conflicts, NULL,
+ wc_ctx->db, local_abspath,
+ FALSE /* temp files */,
+ TRUE /* only tree conflicts */,
scratch_pool, scratch_pool));
if (!conflicts || conflicts->nelts == 0)
Modified: subversion/branches/ra-git/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/update_editor.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/update_editor.c Mon Nov 30 10:24:16 2015
@@ -1812,6 +1812,7 @@ delete_entry(const char *path,
{
if (eb->conflict_func)
SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, local_abspath,
+ kind,
tree_conflict,
NULL /* merge_options */,
eb->conflict_func,
@@ -1862,13 +1863,14 @@ add_directory(const char *path,
SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));
SVN_ERR(make_dir_baton(&db, path, eb, pb, TRUE, pool));
- SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
- NULL, eb, pb, db->pool, scratch_pool));
*child_baton = db;
if (db->skip_this)
return SVN_NO_ERROR;
+ SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
+ NULL, eb, pb, db->pool, scratch_pool));
+
SVN_ERR(mark_directory_edited(db, pool));
if (strcmp(eb->target_abspath, db->local_abspath) == 0)
@@ -1935,7 +1937,8 @@ add_directory(const char *path,
SVN_ERR_ASSERT(conflicted);
versioned_locally_and_present = FALSE; /* Tree conflict ACTUAL-only node */
}
- else if (status == svn_wc__db_status_normal)
+ else if (status == svn_wc__db_status_normal
+ || status == svn_wc__db_status_incomplete)
{
svn_boolean_t root;
@@ -2752,7 +2755,8 @@ close_directory(void *dir_baton,
db->old_revision,
db->new_repos_relpath,
svn_node_dir, svn_node_dir,
- db->parent_baton->deletion_conflicts
+ (db->parent_baton
+ && db->parent_baton->deletion_conflicts)
? svn_hash_gets(
db->parent_baton->deletion_conflicts,
db->name)
@@ -2813,6 +2817,7 @@ close_directory(void *dir_baton,
if (conflict_skel && eb->conflict_func)
SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, db->local_abspath,
+ svn_node_dir,
conflict_skel,
NULL /* merge_options */,
eb->conflict_func,
@@ -2998,6 +3003,7 @@ absent_node(const char *path,
{
if (eb->conflict_func)
SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, local_abspath,
+ kind,
tree_conflict,
NULL /* merge_options */,
eb->conflict_func,
@@ -3061,13 +3067,13 @@ add_file(const char *path,
SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));
SVN_ERR(make_file_baton(&fb, pb, path, TRUE, pool));
- SVN_ERR(calculate_repos_relpath(&fb->new_repos_relpath, fb->local_abspath,
- NULL, eb, pb, fb->pool, pool));
*file_baton = fb;
if (fb->skip_this)
return SVN_NO_ERROR;
+ SVN_ERR(calculate_repos_relpath(&fb->new_repos_relpath, fb->local_abspath,
+ NULL, eb, pb, fb->pool, pool));
SVN_ERR(mark_file_edited(fb, pool));
/* The file_pool can stick around for a *long* time, so we want to
@@ -3118,7 +3124,8 @@ add_file(const char *path,
SVN_ERR_ASSERT(conflicted);
versioned_locally_and_present = FALSE; /* Tree conflict ACTUAL-only node */
}
- else if (status == svn_wc__db_status_normal)
+ else if (status == svn_wc__db_status_normal
+ || status == svn_wc__db_status_incomplete)
{
svn_boolean_t root;
@@ -3545,15 +3552,23 @@ lazy_open_target(svn_stream_t **stream,
apr_pool_t *scratch_pool)
{
struct handler_baton *hb = baton;
+ svn_wc__db_install_data_t *install_data;
+ /* By convention return value is undefined on error, but we rely
+ on HB->INSTALL_DATA value in window_handler() and abort
+ INSTALL_STREAM if is not NULL on error.
+ So we store INSTALL_DATA to local variable first, to leave
+ HB->INSTALL_DATA unchanged on error. */
SVN_ERR(svn_wc__db_pristine_prepare_install(stream,
- &hb->install_data,
+ &install_data,
&hb->new_text_base_sha1_checksum,
NULL,
hb->fb->edit_baton->db,
hb->fb->dir_baton->local_abspath,
result_pool, scratch_pool));
+ hb->install_data = install_data;
+
return SVN_NO_ERROR;
}
@@ -4536,6 +4551,7 @@ close_file(void *file_baton,
if (conflict_skel && eb->conflict_func)
SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, fb->local_abspath,
+ svn_node_file,
conflict_skel,
NULL /* merge_options */,
eb->conflict_func,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c Mon Nov 30 10:24:16 2015
@@ -535,7 +535,7 @@ svn_wc__wipe_postupgrade(const char *dir
int i;
if (cancel_func)
- SVN_ERR((*cancel_func)(cancel_baton));
+ SVN_ERR(cancel_func(cancel_baton));
err = get_versioned_subdirs(&subdirs, &delete_dir, dir_abspath, TRUE,
scratch_pool, iterpool);
@@ -1434,7 +1434,7 @@ rename_pristine_file(void *baton,
const char *new_abspath
= apr_pstrcat(pool, abspath, PRISTINE_STORAGE_EXT, SVN_VA_NULL);
- SVN_ERR(svn_io_file_rename(abspath, new_abspath, pool));
+ SVN_ERR(svn_io_file_rename2(abspath, new_abspath, FALSE, pool));
}
return SVN_NO_ERROR;
}
@@ -2513,7 +2513,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
/* Renaming the db file is what makes the pre-wcng into a wcng */
db_from = svn_wc__adm_child(data.root_abspath, SDB_FILE, scratch_pool);
db_to = svn_wc__adm_child(local_abspath, SDB_FILE, scratch_pool);
- SVN_ERR(svn_io_file_rename(db_from, db_to, scratch_pool));
+ SVN_ERR(svn_io_file_rename2(db_from, db_to, FALSE, scratch_pool));
/* Now we have a working wcng, tidy up the droppings */
SVN_ERR(svn_wc__db_open(&db, NULL /* ### config */, FALSE, FALSE,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql Mon Nov 30 10:24:16 2015
@@ -598,27 +598,32 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED
ANALYZE sqlite_master; /* Creates empty sqlite_stat1 if necessary */
DELETE FROM sqlite_stat1
-WHERE tbl in ('NODES', 'ACTUAL_NODE', 'LOCK', 'WC_LOCK');
+WHERE tbl in ('NODES', 'ACTUAL_NODE', 'LOCK', 'WC_LOCK', 'EXTERNALS');
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('NODES', 'sqlite_autoindex_NODES_1', '8000 8000 2 1');
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('NODES', 'I_NODES_PARENT', '8000 8000 10 2 1');
/* Tell a lie: We ignore that 99.9% of all moved_to values are NULL */
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('NODES', 'I_NODES_MOVED', '8000 8000 1 1');
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('ACTUAL_NODE', 'sqlite_autoindex_ACTUAL_NODE_1', '8000 8000 1');
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('ACTUAL_NODE', 'I_ACTUAL_PARENT', '8000 8000 10 1');
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('LOCK', 'sqlite_autoindex_LOCK_1', '100 100 1');
-INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
('WC_LOCK', 'sqlite_autoindex_WC_LOCK_1', '100 100 1');
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('EXTERNALS','sqlite_autoindex_EXTERNALS_1', '100 100 1');
+INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('EXTERNALS','I_EXTERNALS_DEFINED', '100 100 3 1');
+
/* sqlite_autoindex_WORK_QUEUE_1 doesn't exist because WORK_QUEUE is
a INTEGER PRIMARY KEY AUTOINCREMENT table */
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql Mon Nov 30 10:24:16 2015
@@ -1286,7 +1286,10 @@ WHERE (wc_id = ?1 AND local_relpath = ?2
OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
-- STMT_PRAGMA_LOCKING_MODE
-PRAGMA locking_mode = exclusive
+PRAGMA locking_mode = exclusive;
+/* Testing shows DELETE is faster than TRUNCATE on NFS and
+ exclusive-locking is mostly used on remote file systems. */
+PRAGMA journal_mode = DELETE
/* ------------------------------------------------------------------------- */
@@ -1781,6 +1784,10 @@ WHERE wc_id = ?1
AND op_depth = 0
AND (inherited_props not null)
+-- STMT_HAVE_STAT1_TABLE
+SELECT 1 FROM sqlite_master WHERE name='sqlite_stat1' AND type='table'
+LIMIT 1
+
/* ------------------------------------------------------------------------- */
/* Grab all the statements related to the schema. */
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc.h Mon Nov 30 10:24:16 2015
@@ -190,6 +190,10 @@ extern "C" {
/* A version < this has no work queue (see workqueue.h). */
#define SVN_WC__HAS_WORK_QUEUE 13
+/* While we still have this DB version we should verify if there is
+ sqlite_stat1 table on opening */
+#define SVN_WC__ENSURE_STAT1_TABLE 31
+
/* Return a string indicating the released version (or versions) of
* Subversion that used WC format number WC_FORMAT, or some other
* suitable string if no released version used WC_FORMAT.
@@ -631,9 +635,11 @@ svn_wc__write_check(svn_wc__db_t *db,
*/
svn_error_t *
svn_wc__read_conflicts(const apr_array_header_t **conflicts,
+ svn_skel_t **conflict_skel,
svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t create_tempfiles,
+ svn_boolean_t only_tree_conflict,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c Mon Nov 30 10:24:16 2015
@@ -6698,8 +6698,14 @@ svn_wc__db_op_mark_resolved_internal(svn
conflict_data = svn_sqlite__column_blob(stmt, 2, &conflict_len,
scratch_pool);
- conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool);
SVN_ERR(svn_sqlite__reset(stmt));
+ SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
+ if (!conflict_data)
+ return SVN_NO_ERROR;
+
+ conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool);
+
SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts,
db, wcroot->abspath,
@@ -6731,8 +6737,6 @@ svn_wc__db_op_mark_resolved_internal(svn
SVN_ERR(svn_sqlite__step_done(stmt));
}
- SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
-
return SVN_NO_ERROR;
}
@@ -6799,6 +6803,75 @@ clear_moved_to(svn_wc__db_wcroot_t *wcro
return SVN_NO_ERROR;
}
+/* Helper function for op_revert_txn. Raises move tree conflicts on
+ descendants to ensure database stability on a non recursive revert
+ of an ancestor that contains a possible move related tree conflict.
+ */
+static svn_error_t *
+revert_maybe_raise_moved_away(svn_wc__db_wcroot_t * wcroot,
+ svn_wc__db_t *db,
+ const char *local_relpath,
+ int op_depth_below,
+ apr_pool_t *scratch_pool)
+{
+ svn_skel_t *conflict;
+ svn_wc_operation_t operation;
+ svn_boolean_t tree_conflicted;
+ const apr_array_header_t *locations;
+ svn_wc_conflict_reason_t reason;
+ svn_wc_conflict_action_t action;
+
+ SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL, wcroot,
+ local_relpath,
+ scratch_pool, scratch_pool));
+
+ if (!conflict)
+ return SVN_NO_ERROR;
+
+ SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, NULL, NULL,
+ &tree_conflicted,
+ db, wcroot->abspath,
+ conflict,
+ scratch_pool, scratch_pool));
+
+ if (!tree_conflicted
+ || (operation != svn_wc_operation_update
+ && operation != svn_wc_operation_switch))
+ {
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
+ NULL,
+ db, wcroot->abspath,
+ conflict,
+ scratch_pool,
+ scratch_pool));
+
+ if (reason == svn_wc_conflict_reason_deleted
+ || reason == svn_wc_conflict_reason_replaced)
+ {
+ SVN_ERR(svn_wc__db_op_raise_moved_away_internal(
+ wcroot, local_relpath, op_depth_below, db,
+ operation, action,
+ (locations && locations->nelts > 0)
+ ? APR_ARRAY_IDX(locations, 0,
+ const svn_wc_conflict_version_t *)
+ : NULL,
+ (locations && locations->nelts > 1)
+ ? APR_ARRAY_IDX(locations, 1,
+ const svn_wc_conflict_version_t *)
+ : NULL,
+ scratch_pool));
+
+ /* Transform the move information into revert information */
+ SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+ STMT_MOVE_NOTIFY_TO_REVERT));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* Baton for op_revert_txn and op_revert_recursive_txn */
struct revert_baton_t
{
@@ -6823,9 +6896,7 @@ op_revert_txn(void *baton,
svn_boolean_t moved_here;
int affected_rows;
const char *moved_to;
- int op_depth_increased = 0;
int op_depth_below;
- svn_skel_t *conflict;
/* ### Similar structure to op_revert_recursive_txn, should they be
combined? */
@@ -6887,16 +6958,11 @@ op_revert_txn(void *baton,
local_relpath, op_depth,
moved_to, NULL, scratch_pool));
}
- else
- {
- SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, wcroot,
- local_relpath,
- scratch_pool, scratch_pool));
- }
-
if (op_depth > 0 && op_depth == relpath_depth(local_relpath))
{
+ int op_depth_increased;
+
/* Can't do non-recursive revert if children exist */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_GE_OP_DEPTH_CHILDREN));
@@ -6935,54 +7001,12 @@ op_revert_txn(void *baton,
/* If this node was moved-here, clear moved-to at the move source. */
if (moved_here)
SVN_ERR(clear_moved_to(wcroot, local_relpath, scratch_pool));
- }
-
- if (op_depth_increased && conflict)
- {
- svn_wc_operation_t operation;
- svn_boolean_t tree_conflicted;
- const apr_array_header_t *locations;
-
- SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, NULL, NULL,
- &tree_conflicted,
- db, wcroot->abspath,
- conflict,
- scratch_pool, scratch_pool));
- if (tree_conflicted
- && (operation == svn_wc_operation_update
- || operation == svn_wc_operation_switch))
- {
- svn_wc_conflict_reason_t reason;
- svn_wc_conflict_action_t action;
-
- SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
- NULL,
- db, wcroot->abspath,
- conflict,
- scratch_pool,
- scratch_pool));
- if (reason == svn_wc_conflict_reason_deleted
- || reason == svn_wc_conflict_reason_replaced)
- {
- SVN_ERR(svn_wc__db_op_raise_moved_away_internal(
- wcroot, local_relpath, op_depth_below, db,
- operation, action,
- (locations && locations->nelts > 0)
- ? APR_ARRAY_IDX(locations, 0,
- const svn_wc_conflict_version_t *)
- : NULL,
- (locations && locations->nelts > 1)
- ? APR_ARRAY_IDX(locations, 1,
- const svn_wc_conflict_version_t *)
- : NULL,
- scratch_pool));
-
- /* Transform the move information into revert information */
- SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
- STMT_MOVE_NOTIFY_TO_REVERT));
- }
- }
+ /* If the node was moved itself, we don't have interesting moved
+ children (and the move itself was already broken) */
+ if (op_depth_increased && !moved_to)
+ SVN_ERR(revert_maybe_raise_moved_away(wcroot, db, local_relpath,
+ op_depth_below, scratch_pool));
}
if (rvb->clear_changelists)
@@ -8740,6 +8764,45 @@ svn_wc__db_op_delete_many(svn_wc__db_t *
scratch_pool));
}
+/* Helper function for read_info() to provide better diagnostics than just
+ asserting.
+
+ ### BH: Yes this code is ugly, and that is why I only introduce it in
+ ### read_info(). But we really need something to determine the root cause
+ ### of this problem to diagnose why TortoiseSVN users were seeing all those
+ ### assertions.
+
+ Adds an error to the *err chain if invalid values are encountered. In that
+ case the value is set to the first value in the map, assuming that caller
+ will just return the combined error.
+ */
+static int
+column_token_err(svn_error_t **err,
+ svn_sqlite__stmt_t *stmt,
+ int column,
+ const svn_token_map_t *map)
+{
+ svn_error_t *err2;
+ const char *word = svn_sqlite__column_text(stmt, column, NULL);
+ int value;
+
+ /* svn_token__from_word_err() handles NULL for us */
+ err2 = svn_token__from_word_err(&value, map, word);
+
+ if (err2)
+ {
+ *err = svn_error_compose_create(
+ *err,
+ svn_error_createf(
+ SVN_ERR_WC_CORRUPT, err2,
+ _("Encountered invalid node state in column %d of "
+ "info query to working copy database"),
+ column));
+ value = map[0].val;
+ }
+
+ return value;
+}
/* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
@@ -8807,11 +8870,11 @@ read_info(svn_wc__db_status_t *status,
svn_node_kind_t node_kind;
op_depth = svn_sqlite__column_int(stmt_info, 0);
- node_kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
+ node_kind = column_token_err(&err, stmt_info, 4, kind_map);
if (status)
{
- *status = svn_sqlite__column_token(stmt_info, 3, presence_map);
+ *status = column_token_err(&err, stmt_info, 3, presence_map);
if (op_depth != 0) /* WORKING */
err = svn_error_compose_create(err,
@@ -8863,14 +8926,11 @@ read_info(svn_wc__db_status_t *status,
if (depth)
{
if (node_kind != svn_node_dir)
- {
- *depth = svn_depth_unknown;
- }
+ *depth = svn_depth_unknown;
+ else if (svn_sqlite__column_is_null(stmt_info, 11))
+ *depth = svn_depth_unknown;
else
- {
- *depth = svn_sqlite__column_token_null(stmt_info, 11, depth_map,
- svn_depth_unknown);
- }
+ *depth = column_token_err(&err, stmt_info, 11, depth_map);
}
if (checksum)
{
@@ -9434,8 +9494,8 @@ read_children_info(svn_wc__db_wcroot_t *
moved_to_relpath,
result_pool);
- shadow_op_relpath = svn_relpath_limit(child_relpath, op_depth,
- scratch_pool);
+ shadow_op_relpath = svn_relpath_prefix(child_relpath, op_depth,
+ scratch_pool);
moved_to->shadow_op_root_abspath =
svn_dirent_join(wcroot->abspath, shadow_op_relpath,
@@ -9624,8 +9684,8 @@ read_single_info(const struct svn_wc__db
moved_to_relpath,
result_pool);
- cur_relpath = svn_relpath_limit(local_relpath, op_depth,
- scratch_pool);
+ cur_relpath = svn_relpath_prefix(local_relpath, op_depth,
+ scratch_pool);
move->shadow_op_root_abspath = svn_dirent_join(wcroot->abspath,
cur_relpath,
@@ -12700,7 +12760,8 @@ scan_addition(svn_wc__db_status_t *statu
/* Calculate the op root local path components */
- op_root_relpath = svn_relpath_limit(local_relpath, op_depth, scratch_pool);
+ op_root_relpath = svn_relpath_prefix(local_relpath, op_depth,
+ scratch_pool);
repos_prefix_path = svn_relpath_skip_ancestor(op_root_relpath,
local_relpath);
@@ -12819,8 +12880,8 @@ scan_addition(svn_wc__db_status_t *statu
/* Skip to op_depth */
tmp = op_root_relpath;
- op_root_relpath = svn_relpath_limit(op_root_relpath, op_depth,
- scratch_pool);
+ op_root_relpath = svn_relpath_prefix(op_root_relpath, op_depth,
+ scratch_pool);
repos_prefix_path = svn_relpath_join(
svn_relpath_skip_ancestor(op_root_relpath, tmp),
repos_prefix_path, scratch_pool);
@@ -13029,8 +13090,8 @@ svn_wc__db_scan_moved(const char **moved
/* The deleted node is either where we moved from, or one of its ancestors */
if (moved_from_delete_abspath)
{
- const char *tmp = svn_relpath_limit(moved_from_op_root_relpath,
- moved_from_op_depth, scratch_pool);
+ const char *tmp = svn_relpath_prefix(moved_from_op_root_relpath,
+ moved_from_op_depth, scratch_pool);
*moved_from_delete_abspath = svn_dirent_join(wcroot->abspath, tmp,
scratch_pool);
@@ -13236,8 +13297,8 @@ svn_wc__db_scan_moved_to_internal(const
*move_dst_relpath = apr_pstrdup(result_pool, dst_relpath);
if (delete_relpath)
- *delete_relpath = svn_relpath_limit(local_relpath, delete_op_depth,
- result_pool);
+ *delete_relpath = svn_relpath_prefix(local_relpath, delete_op_depth,
+ result_pool);
}
return SVN_NO_ERROR;
@@ -13942,6 +14003,7 @@ svn_wc__db_get_conflict_marker_files(apr
svn_error_t *
svn_wc__db_read_conflict(svn_skel_t **conflict,
svn_node_kind_t *kind,
+ apr_hash_t **props,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -13955,7 +14017,7 @@ svn_wc__db_read_conflict(svn_skel_t **co
local_abspath, scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- return svn_error_trace(svn_wc__db_read_conflict_internal(conflict, kind,
+ return svn_error_trace(svn_wc__db_read_conflict_internal(conflict, kind, props,
wcroot, local_relpath,
result_pool,
scratch_pool));
@@ -13964,6 +14026,7 @@ svn_wc__db_read_conflict(svn_skel_t **co
svn_error_t *
svn_wc__db_read_conflict_internal(svn_skel_t **conflict,
svn_node_kind_t *kind,
+ apr_hash_t **props,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
@@ -13974,6 +14037,8 @@ svn_wc__db_read_conflict_internal(svn_sk
if (kind)
*kind = svn_node_none;
+ if (props)
+ *props = NULL;
/* Check if we have a conflict in ACTUAL */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -13982,59 +14047,82 @@ svn_wc__db_read_conflict_internal(svn_sk
SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (!have_row || kind)
+ if (have_row)
{
- /* Do this while stmt is still open to avoid closing the sqlite
- transaction and then reopening. */
- svn_sqlite__stmt_t *stmt_node;
- svn_error_t *err;
- svn_boolean_t have_info = FALSE;
+ apr_size_t cfl_len;
+ const void *cfl_data;
- err = svn_sqlite__get_statement(&stmt_node, wcroot->sdb,
- STMT_SELECT_NODE_INFO);
+ /* svn_skel__parse doesn't copy data, so store in result_pool */
+ cfl_data = svn_sqlite__column_blob(stmt, 2, &cfl_len, result_pool);
- if (err)
- stmt_node = NULL;
+ if (cfl_data)
+ *conflict = svn_skel__parse(cfl_data, cfl_len, result_pool);
else
- err = svn_sqlite__bindf(stmt_node, "is", wcroot->wc_id,
- local_relpath);
+ *conflict = NULL;
- if (!err)
- err = svn_sqlite__step(&have_info, stmt_node);
-
- if (!err && kind && have_info)
+ if (props)
{
- svn_wc__db_status_t status;
- int op_depth = svn_sqlite__column_int(stmt_node, 0);
-
- status = svn_sqlite__column_token(stmt_node, 3, presence_map);
+ svn_error_t *err;
- if (op_depth > 0)
- err = convert_to_working_status(&status, status);
+ err = svn_error_trace(svn_sqlite__column_properties(props, stmt, 1,
+ result_pool,
+ scratch_pool));
- if (!err && (status == svn_wc__db_status_normal
- || status == svn_wc__db_status_added
- || status == svn_wc__db_status_deleted
- || status == svn_wc__db_status_incomplete))
- {
- *kind = svn_sqlite__column_token(stmt_node, 4, kind_map);
- }
+ if (err)
+ return svn_error_compose_create(err, svn_sqlite__reset(stmt));
}
+ }
+ else
+ *conflict = NULL;
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (!have_row || kind || (props && !*props))
+ {
+ svn_error_t *err = NULL;
+ svn_boolean_t have_info = FALSE;
- if (stmt_node)
- err = svn_error_compose_create(err,
- svn_sqlite__reset(stmt_node));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_NODE_INFO));
- if (!have_row || err)
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
+ local_relpath));
+
+ SVN_ERR(svn_sqlite__step(&have_info, stmt));
+
+ if (have_info)
{
- SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+ if (kind)
+ {
+ svn_wc__db_status_t status;
+ int op_depth = svn_sqlite__column_int(stmt, 0);
+
+ status = svn_sqlite__column_token(stmt, 3, presence_map);
+
+ if (op_depth > 0)
+ err = convert_to_working_status(&status, status);
+
+ if (!err && (status == svn_wc__db_status_normal
+ || status == svn_wc__db_status_added
+ || status == svn_wc__db_status_deleted
+ || status == svn_wc__db_status_incomplete))
+ {
+ *kind = svn_sqlite__column_token(stmt, 4, kind_map);
+ }
+ }
- if (have_info)
+ /* Need props, and no props in ACTUAL? */
+ if (!err && (props && !*props))
{
- *conflict = NULL;
- return SVN_NO_ERROR;
+ err = svn_sqlite__column_properties(props, stmt, 14,
+ result_pool, scratch_pool);
}
+ }
+
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+ if (!have_row && !have_info)
+ {
return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
_("The node '%s' was not found."),
path_for_error_message(wcroot,
@@ -14043,20 +14131,7 @@ svn_wc__db_read_conflict_internal(svn_sk
}
}
- {
- apr_size_t cfl_len;
- const void *cfl_data;
-
- /* svn_skel__parse doesn't copy data, so store in result_pool */
- cfl_data = svn_sqlite__column_blob(stmt, 2, &cfl_len, result_pool);
-
- if (cfl_data)
- *conflict = svn_skel__parse(cfl_data, cfl_len, result_pool);
- else
- *conflict = NULL;
-
- return svn_error_trace(svn_sqlite__reset(stmt));
- }
+ return SVN_NO_ERROR;
}
@@ -15102,7 +15177,7 @@ make_copy_txn(svn_wc__db_wcroot_t *wcroo
const char *name = svn_relpath_skip_ancestor(last_repos_relpath,
repos_relpath);
- if (strcmp(name, svn_relpath_basename(local_relpath, NULL)) == 0)
+ if (name && strcmp(name, svn_relpath_basename(local_relpath, NULL)) == 0)
op_depth = last_op_depth;
}
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h Mon Nov 30 10:24:16 2015
@@ -1644,7 +1644,12 @@ svn_wc__db_op_mark_conflict(svn_wc__db_t
apr_pool_t *scratch_pool);
-/* ### caller maintains ACTUAL, and how the resolution occurred. we're just
+/* Clear all or some of the conflicts stored on LOCAL_ABSPATH, if any.
+
+ Any work items that are necessary as part of resolving this node
+ can be passed in WORK_ITEMS.
+
+### caller maintains ACTUAL, and how the resolution occurred. we're just
### recording state.
###
### I'm not sure that these three values are the best way to do this,
@@ -2364,7 +2369,9 @@ svn_wc__db_get_conflict_marker_files(apr
/* Read the conflict information recorded on LOCAL_ABSPATH in *CONFLICT,
an editable conflict skel. If kind is not NULL, also read the node kind
- in *KIND. (SHOW_HIDDEN: false, SHOW_DELETED: true)
+ in *KIND. (SHOW_HIDDEN: false, SHOW_DELETED: true). If props is not NULL
+ read the actual properties in this value if they exist. (Set to NULL in case
+ the node is deleted, etc.)
If the node exists, but does not have a conflict set *CONFLICT to NULL,
otherwise return a SVN_ERR_WC_PATH_NOT_FOUND error.
@@ -2374,6 +2381,7 @@ svn_wc__db_get_conflict_marker_files(apr
svn_error_t *
svn_wc__db_read_conflict(svn_skel_t **conflict,
svn_node_kind_t *kind,
+ apr_hash_t **props,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_pristine.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_pristine.c Mon Nov 30 10:24:16 2015
@@ -333,14 +333,12 @@ pristine_install_txn(svn_sqlite__db_t *s
* an orphan file and it doesn't matter if we overwrite it.) */
{
apr_finfo_t finfo;
- SVN_ERR(svn_stream__install_get_info(&finfo, install_stream, APR_FINFO_SIZE,
- scratch_pool));
- SVN_ERR(svn_io_set_file_read_write(pristine_abspath, TRUE, scratch_pool));
+ SVN_ERR(svn_stream__install_get_info(&finfo, install_stream,
+ APR_FINFO_SIZE, scratch_pool));
SVN_ERR(svn_stream__install_stream(install_stream, pristine_abspath,
- TRUE, scratch_pool));
+ TRUE, scratch_pool));
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_INSERT_PRISTINE));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE));
SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
@@ -383,9 +381,10 @@ svn_wc__db_pristine_prepare_install(svn_
*install_data = apr_pcalloc(result_pool, sizeof(**install_data));
(*install_data)->wcroot = wcroot;
- SVN_ERR(svn_stream__create_for_install(stream,
- temp_dir_abspath,
- result_pool, scratch_pool));
+ SVN_ERR_W(svn_stream__create_for_install(stream,
+ temp_dir_abspath,
+ result_pool, scratch_pool),
+ _("Unable to create pristine install stream"));
(*install_data)->inner_stream = *stream;
@@ -569,7 +568,8 @@ maybe_transfer_one_pristine(svn_wc__db_w
/* Move the file to its target location. (If it is already there, it is
* an orphan file and it doesn't matter if we overwrite it.) */
- err = svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool);
+ err = svn_io_file_rename2(tmp_abspath, pristine_abspath, FALSE,
+ scratch_pool);
/* Maybe the directory doesn't exist yet? */
if (err && APR_STATUS_IS_ENOENT(err->apr_err))
@@ -587,7 +587,8 @@ maybe_transfer_one_pristine(svn_wc__db_w
/* We could create a directory: retry install */
svn_error_clear(err);
- SVN_ERR(svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool));
+ SVN_ERR(svn_io_file_rename2(tmp_abspath, pristine_abspath, FALSE,
+ scratch_pool));
}
else
SVN_ERR(err);
@@ -686,42 +687,6 @@ svn_wc__db_pristine_transfer(svn_wc__db_
-/* Remove the file at FILE_ABSPATH in such a way that we could re-create a
- * new file of the same name at any time thereafter.
- *
- * On Windows, the file will not disappear immediately from the directory if
- * it is still being read so the best thing to do is first rename it to a
- * unique name. */
-static svn_error_t *
-remove_file(const char *file_abspath,
- svn_wc__db_wcroot_t *wcroot,
- svn_boolean_t ignore_enoent,
- apr_pool_t *scratch_pool)
-{
-#ifdef WIN32
- svn_error_t *err;
- const char *temp_abspath;
- const char *temp_dir_abspath
- = pristine_get_tempdir(wcroot, scratch_pool, scratch_pool);
-
- /* To rename the file to a unique name in the temp dir, first create a
- * uniquely named file in the temp dir and then overwrite it. */
- SVN_ERR(svn_io_open_unique_file3(NULL, &temp_abspath, temp_dir_abspath,
- svn_io_file_del_none,
- scratch_pool, scratch_pool));
- err = svn_io_file_rename(file_abspath, temp_abspath, scratch_pool);
- if (err && ignore_enoent && APR_STATUS_IS_ENOENT(err->apr_err))
- svn_error_clear(err);
- else
- SVN_ERR(err);
- file_abspath = temp_abspath;
-#endif
-
- SVN_ERR(svn_io_remove_file2(file_abspath, ignore_enoent, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
/* If the pristine text referenced by SHA1_CHECKSUM in WCROOT/SDB, whose path
* within the pristine store is PRISTINE_ABSPATH, has a reference count of
* zero, delete it (both the database row and the disk file).
@@ -757,8 +722,8 @@ pristine_remove_if_unreferenced_txn(svn_
svn_boolean_t ignore_enoent = TRUE;
#endif
- SVN_ERR(remove_file(pristine_abspath, wcroot, ignore_enoent,
- scratch_pool));
+ SVN_ERR(svn_io_remove_file2(pristine_abspath, ignore_enoent,
+ scratch_pool));
}
return SVN_NO_ERROR;
@@ -870,6 +835,7 @@ pristine_cleanup_wcroot(svn_wc__db_wcroo
{
svn_sqlite__stmt_t *stmt;
svn_error_t *err = NULL;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
/* Find each unreferenced pristine in the DB and remove it. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -879,16 +845,20 @@ pristine_cleanup_wcroot(svn_wc__db_wcroo
svn_boolean_t have_row;
const svn_checksum_t *sha1_checksum;
+ svn_pool_clear(iterpool);
+
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (! have_row)
break;
SVN_ERR(svn_sqlite__column_checksum(&sha1_checksum, stmt, 0,
- scratch_pool));
+ iterpool));
err = pristine_remove_if_unreferenced(wcroot, sha1_checksum,
- scratch_pool);
+ iterpool);
}
+ svn_pool_destroy(iterpool);
+
return svn_error_trace(
svn_error_compose_create(err, svn_sqlite__reset(stmt)));
}
@@ -944,11 +914,28 @@ svn_wc__db_pristine_check(svn_boolean_t
{
const char *pristine_abspath;
svn_node_kind_t kind_on_disk;
+ svn_error_t *err;
SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
sha1_checksum, scratch_pool, scratch_pool));
- SVN_ERR(svn_io_check_path(pristine_abspath, &kind_on_disk, scratch_pool));
- if (kind_on_disk != svn_node_file)
+ err = svn_io_check_path(pristine_abspath, &kind_on_disk, scratch_pool);
+#ifdef WIN32
+ if (err && err->apr_err == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED))
+ {
+ svn_error_clear(err);
+ /* Possible race condition: The filename is locked, but there is no
+ file or dir with this name. Let's fall back on checking the DB.
+
+ This case is triggered by the pristine store tests on deleting
+ a file that is still open via another handle, where this other
+ handle has a FILE_SHARE_DELETE share mode.
+ */
+ }
+ else
+#endif
+ if (err)
+ return svn_error_trace(err);
+ else if (kind_on_disk != svn_node_file)
{
*present = FALSE;
return SVN_NO_ERROR;
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_private.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_private.h Mon Nov 30 10:24:16 2015
@@ -355,6 +355,7 @@ svn_wc__db_fetch_repos_info(const char *
svn_error_t *
svn_wc__db_read_conflict_internal(svn_skel_t **conflict,
svn_node_kind_t *kind,
+ apr_hash_t **props,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *result_pool,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c Mon Nov 30 10:24:16 2015
@@ -377,7 +377,7 @@ create_tree_conflict(svn_skel_t **confli
child_relpath, scratch_pool);
}
- err = svn_wc__db_read_conflict_internal(&conflict, NULL,
+ err = svn_wc__db_read_conflict_internal(&conflict, NULL, NULL,
wcroot, local_relpath,
result_pool, scratch_pool);
if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
@@ -490,9 +490,9 @@ create_node_tree_conflict(svn_skel_t **c
{
update_move_baton_t *umb = nmb->umb;
const char *dst_repos_relpath;
- const char *dst_root_relpath = svn_relpath_limit(nmb->dst_relpath,
- nmb->umb->dst_op_depth,
- scratch_pool);
+ const char *dst_root_relpath = svn_relpath_prefix(nmb->dst_relpath,
+ nmb->umb->dst_op_depth,
+ scratch_pool);
dst_repos_relpath =
svn_relpath_join(nmb->umb->old_version->path_in_repos,
@@ -504,9 +504,9 @@ create_node_tree_conflict(svn_skel_t **c
return svn_error_trace(
create_tree_conflict(conflict_p, umb->wcroot, dst_local_relpath,
- svn_relpath_limit(dst_local_relpath,
- umb->dst_op_depth,
- scratch_pool),
+ svn_relpath_prefix(dst_local_relpath,
+ umb->dst_op_depth,
+ scratch_pool),
umb->db,
umb->old_version, umb->new_version,
umb->operation, old_kind, new_kind,
@@ -2083,8 +2083,8 @@ bump_moved_layer(svn_boolean_t *recurse,
can_bump = FALSE;
}
- src_root_relpath = svn_relpath_limit(src_relpath, src_del_depth,
- scratch_pool);
+ src_root_relpath = svn_relpath_prefix(src_relpath, src_del_depth,
+ scratch_pool);
if (!can_bump)
{
@@ -2095,8 +2095,8 @@ bump_moved_layer(svn_boolean_t *recurse,
return SVN_NO_ERROR;
}
- SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, wcroot,
- src_root_relpath,
+ SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL,
+ wcroot, src_root_relpath,
scratch_pool, scratch_pool));
/* ### TODO: check this is the right sort of tree-conflict? */
@@ -2404,9 +2404,9 @@ svn_wc__db_op_raise_moved_away_internal(
src_repos_relpath,
svn_wc_conflict_reason_moved_away,
action,
- svn_relpath_limit(src_relpath,
- delete_op_depth,
- iterpool),
+ svn_relpath_prefix(src_relpath,
+ delete_op_depth,
+ iterpool),
iterpool, iterpool);
if (!err)
@@ -2450,7 +2450,7 @@ svn_wc__db_op_raise_moved_away(svn_wc__d
VERIFY_USABLE_WCROOT(wcroot);
SVN_WC__DB_WITH_TXN4(
- svn_wc__db_read_conflict_internal(&conflict, NULL,
+ svn_wc__db_read_conflict_internal(&conflict, NULL, NULL,
wcroot, local_relpath,
scratch_pool, scratch_pool),
fetch_conflict_details(&move_src_op_depth,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_util.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_util.c Mon Nov 30 10:24:16 2015
@@ -127,7 +127,7 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
{
svn_node_kind_t kind;
- /* A file stat is much cheaper then a failed database open handled
+ /* A file stat is much cheaper than a failed database open handled
by SQLite. */
SVN_ERR(svn_io_check_path(sdb_abspath, &kind, scratch_pool));
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c Mon Nov 30 10:24:16 2015
@@ -304,7 +304,7 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- if (sdb != NULL)
+ if (sdb && format == FORMAT_FROM_SDB)
SVN_ERR(svn_sqlite__read_schema_version(&format, sdb, scratch_pool));
/* If we construct a wcroot, then we better have a format. */
@@ -456,6 +456,56 @@ read_link_target(const char **link_targe
return SVN_NO_ERROR;
}
+/* Verify if the sqlite_stat1 table exists and if not tries to add
+ this table (but ignores errors on adding the schema) */
+static svn_error_t *
+verify_stats_table(svn_sqlite__db_t *sdb,
+ int format,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ if (format != SVN_WC__ENSURE_STAT1_TABLE)
+ return SVN_NO_ERROR;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_HAVE_STAT1_TABLE));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (!have_row)
+ {
+ svn_error_clear(
+ svn_wc__db_install_schema_statistics(sdb, scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Sqlite transaction helper for opening the db in
+ svn_wc__db_wcroot_parse_local_abspath() to avoid multiple
+ db operations that each obtain and release a lock */
+static svn_error_t *
+fetch_sdb_info(apr_int64_t *wc_id,
+ int *format,
+ svn_sqlite__db_t *sdb,
+ apr_pool_t *scratch_pool)
+{
+ *wc_id = -1;
+ *format = -1;
+
+ SVN_SQLITE__WITH_LOCK4(
+ svn_wc__db_util_fetch_wc_id(wc_id, sdb, scratch_pool),
+ svn_sqlite__read_schema_version(format, sdb, scratch_pool),
+ verify_stats_table(sdb, *format, scratch_pool),
+ SVN_NO_ERROR,
+ sdb);
+
+ return SVN_NO_ERROR;
+}
+
+
svn_error_t *
svn_wc__db_wcroot_parse_local_abspath(svn_wc__db_wcroot_t **wcroot,
const char **local_relpath,
@@ -696,9 +746,10 @@ try_symlink_as_dir:
/* We finally found the database. Construct a wcroot_t for it. */
apr_int64_t wc_id;
+ int format;
svn_error_t *err;
- err = svn_wc__db_util_fetch_wc_id(&wc_id, sdb, scratch_pool);
+ err = fetch_sdb_info(&wc_id, &format, sdb, scratch_pool);
if (err)
{
if (err->apr_err == SVN_ERR_WC_CORRUPT)
@@ -717,7 +768,7 @@ try_symlink_as_dir:
symlink_wcroot_abspath
? symlink_wcroot_abspath
: local_abspath),
- sdb, wc_id, FORMAT_FROM_SDB,
+ sdb, wc_id, format,
db->verify_format,
db->state_pool, scratch_pool);
if (err && (err->apr_err == SVN_ERR_WC_UNSUPPORTED_FORMAT ||
Modified: subversion/branches/ra-git/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/workqueue.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/workqueue.c Mon Nov 30 10:24:16 2015
@@ -257,7 +257,8 @@ install_committed_file(svn_boolean_t *ov
if (! same)
{
- SVN_ERR(svn_io_file_rename(tmp_wfile, file_abspath, scratch_pool));
+ SVN_ERR(svn_io_file_rename2(tmp_wfile, file_abspath, FALSE,
+ scratch_pool));
*overwrote_working = TRUE;
}
@@ -418,13 +419,13 @@ run_postupgrade(work_item_baton_t *wqb,
### The order may matter for some sufficiently old clients.. but
### this code only runs during upgrade after the files had been
### removed earlier during the upgrade. */
- SVN_ERR(svn_io_write_atomic(format_path, SVN_WC__NON_ENTRIES_STRING,
- sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
- NULL, scratch_pool));
-
- SVN_ERR(svn_io_write_atomic(entries_path, SVN_WC__NON_ENTRIES_STRING,
- sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
- NULL, scratch_pool));
+ SVN_ERR(svn_io_write_atomic2(format_path, SVN_WC__NON_ENTRIES_STRING,
+ sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
+ NULL, TRUE, scratch_pool));
+
+ SVN_ERR(svn_io_write_atomic2(entries_path, SVN_WC__NON_ENTRIES_STRING,
+ sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
+ NULL, TRUE, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1106,7 +1107,7 @@ run_prej_install(work_item_baton_t *wqb,
SVN_ERR(svn_wc__db_from_relpath(&local_abspath, db, wri_abspath,
local_relpath, scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, db, local_abspath,
+ SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL, db, local_abspath,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__conflict_read_prop_conflict(&prejfile_abspath,
@@ -1127,9 +1128,9 @@ run_prej_install(work_item_baton_t *wqb,
scratch_pool, scratch_pool));
/* ... and atomically move it into place. */
- SVN_ERR(svn_io_file_rename(tmp_prejfile_abspath,
- prejfile_abspath,
- scratch_pool));
+ SVN_ERR(svn_io_file_rename2(tmp_prejfile_abspath,
+ prejfile_abspath, FALSE,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -1286,7 +1287,7 @@ run_set_text_conflict_markers(work_item_
/* Check if we should combine with a property conflict... */
svn_skel_t *conflicts;
- SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, db, local_abspath,
+ SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL, db, local_abspath,
scratch_pool, scratch_pool));
if (! conflicts)
@@ -1352,7 +1353,8 @@ run_set_property_conflict_marker(work_it
svn_skel_t *conflicts;
apr_hash_t *prop_names;
- SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, db, local_abspath,
+ SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
+ db, local_abspath,
scratch_pool, scratch_pool));
if (! conflicts)
Modified: subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c Mon Nov 30 10:24:16 2015
@@ -48,6 +48,23 @@
#include "svn_dirent_uri.h"
#include "private/svn_fspath.h"
+/* The apache headers define these and they conflict with our definitions. */
+#ifdef PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#endif
+#ifdef PACKAGE_NAME
+#undef PACKAGE_NAME
+#endif
+#ifdef PACKAGE_STRING
+#undef PACKAGE_STRING
+#endif
+#ifdef PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#endif
+#ifdef PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#endif
+#include "svn_private_config.h"
#ifdef APLOG_USE_MODULE
APLOG_USE_MODULE(authz_svn);
@@ -67,6 +84,28 @@ typedef struct authz_svn_config_rec {
const char *force_username_case;
} authz_svn_config_rec;
+/* version where ap_some_auth_required breaks */
+#if AP_MODULE_MAGIC_AT_LEAST(20060110,0)
+/* first version with force_authn hook and ap_some_authn_required()
+ which allows us to work without ap_some_auth_required() */
+# if AP_MODULE_MAGIC_AT_LEAST(20120211,47) || defined(SVN_USE_FORCE_AUTHN)
+# define USE_FORCE_AUTHN 1
+# define IN_SOME_AUTHN_NOTE "authz_svn-in-some-authn"
+# define FORCE_AUTHN_NOTE "authz_svn-force-authn"
+# else
+ /* ap_some_auth_required() is busted and no viable alternative exists */
+# ifndef SVN_ALLOW_BROKEN_HTTPD_AUTH
+# error This Apache httpd has broken auth (CVE-2015-3184)
+# else
+ /* user wants to build anyway */
+# define USE_FORCE_AUTHN 0
+# endif
+# endif
+#else
+ /* old enough that ap_some_auth_required() still works */
+# define USE_FORCE_AUTHN 0
+#endif
+
/*
* Configuration
*/
@@ -832,6 +871,48 @@ access_checker(request_rec *r)
const char *dest_repos_path = NULL;
int status, authn_required;
+#if USE_FORCE_AUTHN
+ /* Use the force_authn() hook available in 2.4.x to work securely
+ * given that ap_some_auth_required() is no longer functional for our
+ * purposes in 2.4.x.
+ */
+ int authn_configured;
+
+ /* We are not configured to run */
+ if (!conf->anonymous || apr_table_get(r->notes, IN_SOME_AUTHN_NOTE)
+ || (! (conf->access_file || conf->repo_relative_access_file)))
+ return DECLINED;
+
+ /* Authentication is configured */
+ authn_configured = ap_auth_type(r) != NULL;
+ if (authn_configured)
+ {
+ /* If the user is trying to authenticate, let him. It doesn't
+ * make much sense to grant anonymous access but deny authenticated
+ * users access, even though you can do that with '$anon' in the
+ * access file.
+ */
+ if (apr_table_get(r->headers_in,
+ (PROXYREQ_PROXY == r->proxyreq)
+ ? "Proxy-Authorization" : "Authorization"))
+ {
+ /* Set the note to force authn regardless of what access_checker_ex
+ hook requires */
+ apr_table_setn(r->notes, FORCE_AUTHN_NOTE, (const char*)1);
+
+ /* provide the proper return so the access_checker hook doesn't
+ * prevent the code from continuing on to the other auth hooks */
+ if (ap_satisfies(r) != SATISFY_ANY)
+ return OK;
+ else
+ return HTTP_FORBIDDEN;
+ }
+ }
+
+#else
+ /* Support for older versions of httpd that have a working
+ * ap_some_auth_required() */
+
/* We are not configured to run */
if (!conf->anonymous
|| (! (conf->access_file || conf->repo_relative_access_file)))
@@ -846,9 +927,10 @@ access_checker(request_rec *r)
if (ap_satisfies(r) != SATISFY_ANY)
return DECLINED;
- /* If the user is trying to authenticate, let him. If anonymous
- * access is allowed, so is authenticated access, by definition
- * of the meaning of '*' in the access file.
+ /* If the user is trying to authenticate, let him. It doesn't
+ * make much sense to grant anonymous access but deny authenticated
+ * users access, even though you can do that with '$anon' in the
+ * access file.
*/
if (apr_table_get(r->headers_in,
(PROXYREQ_PROXY == r->proxyreq)
@@ -860,6 +942,7 @@ access_checker(request_rec *r)
return HTTP_FORBIDDEN;
}
}
+#endif
/* If anon access is allowed, return OK */
status = req_check_access(r, conf, &repos_path, &dest_repos_path);
@@ -868,7 +951,28 @@ access_checker(request_rec *r)
if (!conf->authoritative)
return DECLINED;
+#if USE_FORCE_AUTHN
+ if (authn_configured) {
+ /* We have to check to see if authn is required because if so we must
+ * return DECLINED rather than FORBIDDEN (403) since returning
+ * the 403 leaks information about what paths may exist to
+ * unauthenticated users. Returning DECLINED means apache's request
+ * handling will continue until the authn module itself generates
+ * UNAUTHORIZED (401).
+
+ * We must set a note here in order to use
+ * ap_some_authn_rquired() without triggering an infinite
+ * loop since the call will trigger this function to be
+ * called again. */
+ apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, (const char*)1);
+ authn_required = ap_some_authn_required(r);
+ apr_table_unset(r->notes, IN_SOME_AUTHN_NOTE);
+ if (authn_required)
+ return DECLINED;
+ }
+#else
if (!authn_required)
+#endif
log_access_verdict(APLOG_MARK, r, 0, FALSE, repos_path, dest_repos_path);
return HTTP_FORBIDDEN;
@@ -949,6 +1053,17 @@ auth_checker(request_rec *r)
return OK;
}
+#if USE_FORCE_AUTHN
+static int
+force_authn(request_rec *r)
+{
+ if (apr_table_get(r->notes, FORCE_AUTHN_NOTE))
+ return OK;
+
+ return DECLINED;
+}
+#endif
+
/*
* Module flesh
*/
@@ -965,6 +1080,9 @@ register_hooks(apr_pool_t *p)
* give SSLOptions +FakeBasicAuth a chance to work. */
ap_hook_check_user_id(check_user_id, mod_ssl, NULL, APR_HOOK_FIRST);
ap_hook_auth_checker(auth_checker, NULL, NULL, APR_HOOK_FIRST);
+#if USE_FORCE_AUTHN
+ ap_hook_force_authn(force_authn, NULL, NULL, APR_HOOK_FIRST);
+#endif
ap_register_provider(p,
AUTHZ_SVN__SUBREQ_BYPASS_PROV_GRP,
AUTHZ_SVN__SUBREQ_BYPASS_PROV_NAME,
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/activity.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/activity.c Mon Nov 30 10:24:16 2015
@@ -165,7 +165,7 @@ dav_svn__delete_activity(const dav_svn_r
txn_name = read_txn(pathname, repos->pool);
if (txn_name == NULL)
{
- return dav_svn__new_error(repos->pool, HTTP_NOT_FOUND, 0,
+ return dav_svn__new_error(repos->pool, HTTP_NOT_FOUND, 0, 0,
"could not find activity.");
}
@@ -208,9 +208,9 @@ dav_svn__store_activity(const dav_svn_re
activity_contents = apr_psprintf(repos->pool, "%s\n%s\n",
txn_name, activity_id);
- err = svn_io_write_atomic(final_path,
- activity_contents, strlen(activity_contents),
- NULL /* copy_perms path */, repos->pool);
+ err = svn_io_write_atomic2(final_path,
+ activity_contents, strlen(activity_contents),
+ NULL /* copy_perms path */, TRUE, repos->pool);
if (err)
{
svn_error_t *serr = svn_error_quick_wrap(err,
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h Mon Nov 30 10:24:16 2015
@@ -296,6 +296,10 @@ struct dav_resource_private {
/* was keyword substitution requested using our public CGI interface
(ie: /path/to/item?kw=1)? */
svn_boolean_t keyword_subst;
+
+ /* whether this resource parameters are fixed and won't change
+ between requests. */
+ svn_boolean_t idempotent;
};
@@ -796,28 +800,35 @@ dav_svn__authz_read_func(dav_svn__authz_
If ERROR_ID is 0, SVN_ERR_RA_DAV_REQUEST_FAILED will be used as a
default value for the error code.
+
+ mod_dav is definitive documentation of the parameters, but a
+ guideline to the different error is:
+
+ STATUS is the HTTP status returned to the client.
+
+ ERROR_ID is an additional DAV-specific error such as a violation of
+ the DAV rules. mod_dav.h defines some values but callers can pass
+ others.
+
+ APRERR is any underlying OS/system error.
*/
dav_error *
dav_svn__new_error_svn(apr_pool_t *pool,
int status,
int error_id,
+ apr_status_t aprerr,
const char *desc);
/* A wrapper around mod_dav's dav_new_error, mod_dav_svn uses this
instead of the mod_dav function to enable special mod_dav_svn specific
- processing. See dav_new_error for parameter documentation.
- Note that DESC may be null (it's hard to track this down from
- dav_new_error()'s documentation, but see the dav_error type,
- which says that its desc field may be NULL).
-
- If ERROR_ID is 0, SVN_ERR_RA_DAV_REQUEST_FAILED will be used as a
- default value for the error code.
+ processing. See dav_svn__new_error_svn for additional details.
*/
dav_error *
dav_svn__new_error(apr_pool_t *pool,
int status,
int error_id,
+ apr_status_t aprerr,
const char *desc);
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/deadprops.c Mon Nov 30 10:24:16 2015
@@ -163,6 +163,23 @@ get_value(dav_db *db, const dav_prop_nam
}
+static svn_error_t *
+change_txn_prop(svn_fs_txn_t *txn,
+ const char *propname,
+ const svn_string_t *value,
+ apr_pool_t *scratch_pool)
+{
+ if (strcmp(propname, SVN_PROP_REVISION_AUTHOR) == 0)
+ return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+ "Attempted to modify 'svn:author' property "
+ "on a transaction");
+
+ SVN_ERR(svn_repos_fs_change_txn_prop(txn, propname, value, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
static dav_error *
save_value(dav_db *db, const dav_prop_name *name,
const svn_string_t *const *old_value_p,
@@ -182,7 +199,7 @@ save_value(dav_db *db, const dav_prop_na
/* ignore the unknown namespace of the incoming prop. */
propname = name->name;
else
- return dav_svn__new_error(db->p, HTTP_CONFLICT, 0,
+ return dav_svn__new_error(db->p, HTTP_CONFLICT, 0, 0,
"Properties may only be defined in the "
SVN_DAV_PROP_NS_SVN " and "
SVN_DAV_PROP_NS_CUSTOM " namespaces.");
@@ -213,9 +230,8 @@ save_value(dav_db *db, const dav_prop_na
{
if (resource->working)
{
- serr = svn_repos_fs_change_txn_prop(resource->info->root.txn,
- propname, value,
- subpool);
+ serr = change_txn_prop(resource->info->root.txn, propname,
+ value, subpool);
}
else
{
@@ -254,8 +270,8 @@ save_value(dav_db *db, const dav_prop_na
}
else if (resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION)
{
- serr = svn_repos_fs_change_txn_prop(resource->info->root.txn,
- propname, value, subpool);
+ serr = change_txn_prop(resource->info->root.txn, propname,
+ value, subpool);
}
else
{
@@ -312,7 +328,7 @@ db_open(apr_pool_t *p,
changing unversioned rev props. Remove this someday: see IZ #916. */
if (! (resource->baselined
&& resource->type == DAV_RESOURCE_TYPE_VERSION))
- return dav_svn__new_error(p, HTTP_CONFLICT, 0,
+ return dav_svn__new_error(p, HTTP_CONFLICT, 0, 0,
"Properties may only be changed on working "
"resources.");
}
@@ -463,7 +479,7 @@ decode_property_value(const svn_string_t
*out_propval_p = svn_base64_decode_string(maybe_encoded_propval,
pool);
else
- return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
"Unknown property encoding");
break;
}
@@ -510,7 +526,7 @@ db_store(dav_db *db,
if (absent && ! elem->first_child)
/* ### better error check */
- return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
apr_psprintf(pool,
"'%s' cannot be specified on the "
"value without specifying an "
@@ -560,8 +576,8 @@ db_remove(dav_db *db, const dav_prop_nam
/* Working Baseline or Working (Version) Resource */
if (db->resource->baselined)
if (db->resource->working)
- serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn,
- propname, NULL, subpool);
+ serr = change_txn_prop(db->resource->info->root.txn, propname,
+ NULL, subpool);
else
/* ### VIOLATING deltaV: you can't proppatch a baseline, it's
not a working resource! But this is how we currently
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c Mon Nov 30 10:24:16 2015
@@ -239,7 +239,7 @@ get_last_modified_time(const char **date
}
if (timeval)
- memcpy(timeval, &timeval_tmp, sizeof(*timeval));
+ *timeval = timeval_tmp;
if (! datestring)
return 0;
@@ -787,20 +787,30 @@ insert_prop_internal(const dav_resource
case SVN_PROPID_deadprop_count:
{
- unsigned int propcount;
- apr_hash_t *proplist;
+ svn_boolean_t has_props;
if (resource->type != DAV_RESOURCE_TYPE_REGULAR)
return DAV_PROP_INSERT_NOTSUPP;
- serr = svn_fs_node_proplist(&proplist,
- resource->info->root.root,
- resource->info->repos_path, scratch_pool);
+ /* Retrieving the actual properties is quite expensive while
+ svn clients only want to know if there are properties, by
+ using this svn defined property.
+
+ Our and and SvnKit's implementation of the ra layer check
+ for '> 0' to provide the boolean if the node has custom
+ properties or not, so starting with 1.9 we just provide
+ "1" or "0".
+ */
+ serr = svn_fs_node_has_props(&has_props,
+ resource->info->root.root,
+ resource->info->repos_path,
+ scratch_pool);
+
if (serr != NULL)
{
ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
resource->info->r,
- "Can't fetch proplist of '%s': "
+ "Can't fetch has properties on '%s': "
"%s",
resource->info->repos_path,
serr->message);
@@ -809,8 +819,7 @@ insert_prop_internal(const dav_resource
break;
}
- propcount = apr_hash_count(proplist);
- value = apr_psprintf(scratch_pool, "%u", propcount);
+ value = has_props ? "1" : "0";
break;
}