You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by as...@apache.org on 2012/11/24 21:29:48 UTC
svn commit: r1413258 [20/33] - in /subversion/branches/compressed-pristines:
./ build/ build/ac-macros/ build/generator/ build/generator/templates/
contrib/client-side/emacs/ contrib/server-side/fsfsfixer/ notes/
notes/directory-index/ subversion/ subv...
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.h?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db.h Sat Nov 24 20:29:11 2012
@@ -255,7 +255,7 @@ typedef struct svn_wc__db_lock_t {
*/
svn_error_t *
svn_wc__db_open(svn_wc__db_t **db,
- const svn_config_t *config,
+ svn_config_t *config,
svn_boolean_t auto_upgrade,
svn_boolean_t enforce_empty_wq,
apr_pool_t *result_pool,
@@ -370,7 +370,7 @@ svn_wc__db_get_wcroot(const char **wcroo
In the BASE tree, each node corresponds to a particular node-rev in the
repository. It can be a mixed-revision tree. Each node holds either a
copy of the node-rev as it exists in the repository (if presence =
- 'normal'), or a place-holder (if presence = 'absent' or 'excluded' or
+ 'normal'), or a place-holder (if presence = 'server-excluded' or 'excluded' or
'not-present').
@{
@@ -409,6 +409,10 @@ svn_wc__db_get_wcroot(const char **wcroo
when the value of NEW_ACTUAL_PROPS matches NEW_PROPS, store NULL in
ACTUAL, to mark the properties unmodified.
+ If NEW_IPROPS is not NULL, then it is a depth-first ordered array of
+ svn_prop_inherited_item_t * structures that is set as the base node's
+ inherited_properties.
+
Any work items that are necessary as part of this node construction may
be passed in WORK_ITEMS.
@@ -432,6 +436,7 @@ svn_wc__db_base_add_directory(svn_wc__db
const svn_skel_t *conflict,
svn_boolean_t update_actual_props,
apr_hash_t *new_actual_props,
+ apr_array_header_t *new_iprops,
const svn_skel_t *work_items,
apr_pool_t *scratch_pool);
@@ -1036,6 +1041,7 @@ svn_wc__db_external_add_file(svn_wc__db_
svn_revnum_t revision,
const apr_hash_t *props,
+ apr_array_header_t *iprops,
svn_revnum_t changed_rev,
apr_time_t changed_date,
@@ -1356,7 +1362,7 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t
apr_pool_t *scratch_pool);
-/* ### do we need svn_wc__db_op_copy_absent() ?? */
+/* ### do we need svn_wc__db_op_copy_server_excluded() ?? */
/* ### add a new versioned directory. a list of children is NOT passed
@@ -1923,7 +1929,7 @@ struct svn_wc__db_info_t {
svn_boolean_t incomplete; /* TRUE if a working node is incomplete */
const char *moved_to_abspath; /* Only on op-roots. See svn_wc_status3_t. */
- svn_boolean_t moved_here; /* On both op-roots and children. */
+ svn_boolean_t moved_here; /* Only on op-roots. */
svn_boolean_t file_external;
};
@@ -2084,6 +2090,39 @@ svn_wc__db_read_pristine_props(apr_hash_
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Read a BASE node's inherited property information.
+
+ Set *IPROPS to to a depth-first ordered array of
+ svn_prop_inherited_item_t * structures representing the cached
+ inherited properties for the BASE node at LOCAL_ABSPATH.
+
+ If no cached properties are found, then set *IPROPS to NULL.
+ If LOCAL_ABSPATH represents the root of the repository, then set
+ *IPROPS to an empty array.
+
+ Allocate *IPROPS in RESULT_POOL, use SCRATCH_POOL for temporary
+ allocations. */
+svn_error_t *
+svn_wc__db_read_cached_iprops(apr_array_header_t **iprops,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Find BASE nodes with cached inherited properties.
+
+ Set *IPROPS_PATHS to a hash mapping const char * absolute working copy
+ paths to the same for each path in the working copy at or below
+ LOCAL_ABSPATH, limited by DEPTH, that has cached inherited properties
+ for the BASE node of the path. Allocate *IPROP_PATHS in RESULT_POOL.
+ Use SCRATCH_POOL for temporary allocations. */
+svn_error_t *
+svn_wc__db_get_children_with_cached_iprops(apr_hash_t **iprop_paths,
+ svn_depth_t depth,
+ const char *local_abspath,
+ svn_wc__db_t *db,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/** Obtain a mapping of const char * local_abspaths to const svn_string_t*
* property values in *VALUES, of all PROPNAME properties on LOCAL_ABSPATH
@@ -2396,6 +2435,12 @@ svn_wc__db_global_update(svn_wc__db_t *d
EXCLUDE_RELPATHS is a hash containing const char *local_relpath. Nodes
for pathnames contained in EXCLUDE_RELPATHS are not touched by this
function. These pathnames should be paths relative to the wcroot.
+
+ If WCROOT_IPROPS is not NULL it is a hash mapping const char * absolute
+ working copy paths to depth-first ordered arrays of
+ svn_prop_inherited_item_t * structures. If LOCAL_ABSPATH exists in
+ WCROOT_IPROPS, then set the hashed value as the node's inherited
+ properties.
*/
svn_error_t *
svn_wc__db_op_bump_revisions_post_update(svn_wc__db_t *db,
@@ -2406,6 +2451,7 @@ svn_wc__db_op_bump_revisions_post_update
const char *new_repos_uuid,
svn_revnum_t new_revision,
apr_hash_t *exclude_relpaths,
+ apr_hash_t *wcroot_iprops,
apr_pool_t *scratch_pool);
@@ -2747,6 +2793,23 @@ svn_wc__db_upgrade_get_repos_id(apr_int6
const char *repos_root_url,
apr_pool_t *scratch_pool);
+/* Upgrade the metadata concerning the WC at WCROOT_ABSPATH, in DB,
+ * to the SVN_WC__VERSION format.
+ *
+ * This function is used for upgrading wc-ng working copies to a newer
+ * wc-ng format. If a pre-1.7 working copy is found, this function
+ * returns SVN_ERR_WC_UPGRADE_REQUIRED.
+ *
+ * Upgrading subdirectories of a working copy is not supported.
+ * If WCROOT_ABSPATH is not a working copy root SVN_ERR_WC_INVALID_OP_ON_CWD
+ * is returned.
+ */
+svn_error_t *
+svn_wc__db_bump_format(int *result_format,
+ const char *wcroot_abspath,
+ svn_wc__db_t *db,
+ apr_pool_t *scratch_pool);
+
/* @} */
@@ -3136,6 +3199,21 @@ svn_wc__db_follow_moved_to(apr_array_hea
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Update a moved-away tree conflict victim at VICTIM_ABSPATH with changes
+ * brought in by the update operation which flagged the tree conflict.
+ * Set *WORK_ITEMS to a list of work items, allocated in RESULT_POOL, that
+ * need to run as part of marking the conflict resolved. */
+svn_error_t *
+svn_wc__db_update_moved_away_conflict_victim(svn_skel_t **work_items,
+ const char *victim_abspath,
+ svn_wc__db_t *db,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* @} */
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_private.h?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_private.h Sat Nov 24 20:29:11 2012
@@ -36,7 +36,7 @@
struct svn_wc__db_t {
/* We need the config whenever we run into a new WC directory, in order
to figure out where we should look for the corresponding datastore. */
- const svn_config_t *config;
+ svn_config_t *config;
/* Should we attempt to automatically upgrade the database when it is
opened, and found to be not-current? */
@@ -159,6 +159,24 @@ svn_wc__db_wcroot_parse_local_abspath(sv
#define VERIFY_USABLE_WCROOT(wcroot) SVN_ERR_ASSERT( \
(wcroot) != NULL && (wcroot)->format == SVN_WC__VERSION)
+/* Calculates the depth of the relpath below "" */
+APR_INLINE static int
+relpath_depth(const char *relpath)
+{
+ int n = 1;
+ if (*relpath == '\0')
+ return 0;
+
+ do
+ {
+ if (*relpath == '/')
+ n++;
+ }
+ while (*(++relpath));
+
+ return n;
+}
+
/* */
svn_error_t *
@@ -181,6 +199,7 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
const char *dir_abspath,
const char *sdb_fname,
svn_sqlite__mode_t smode,
+ svn_boolean_t exclusive,
const char *const *my_statements,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -218,6 +237,50 @@ svn_wc__db_read_info_internal(svn_wc__db
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Like svn_wc__db_scan_deletion(), but with WCROOT+LOCAL_RELPATH instead of
+ DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */
+svn_error_t *
+svn_wc__db_scan_deletion_internal(const char **base_del_relpath,
+ const char **moved_to_relpath,
+ const char **work_del_relpath,
+ const char **moved_to_op_root_relpath,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Like svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH instead of
+ DB+LOCAL_ABSPATH and outputting REPOS_ID instead of URL+UUID. */
+svn_error_t *
+svn_wc__db_base_get_info_internal(svn_wc__db_status_t *status,
+ svn_kind_t *kind,
+ svn_revnum_t *revision,
+ const char **repos_relpath,
+ apr_int64_t *repos_id,
+ svn_revnum_t *changed_rev,
+ apr_time_t *changed_date,
+ const char **changed_author,
+ svn_depth_t *depth,
+ const svn_checksum_t **checksum,
+ const char **target,
+ svn_wc__db_lock_t **lock,
+ svn_boolean_t *had_props,
+ svn_boolean_t *update_root,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+
+/* Like svn_wc__db_read_conflict(), but with WCROOT+LOCAL_RELPATH instead of
+ DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */
+svn_error_t *
+svn_wc__db_read_conflict_internal(svn_skel_t **conflict,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Transaction handling */
Added: subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_update_move.c?rev=1413258&view=auto
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_update_move.c (added)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_update_move.c Sat Nov 24 20:29:11 2012
@@ -0,0 +1,739 @@
+/*
+ * wc_db_update_move.c : updating moves during tree-conflict resolution
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+/* This editor is used during resolution of tree conflicts.
+ *
+ * An operation such as update can produce incoming changes for a
+ * locally moved-away subtree, causing a tree-conflict to be flagged.
+ * This editor transfers these changes from the moved-away part of the
+ * working copy to the corresponding moved-here part of the working copy.
+ *
+ * Both the driver and receiver components of the editor are implemented
+ * in this file.
+ */
+
+#define SVN_WC__I_AM_WC_DB
+
+#include "svn_checksum.h"
+#include "svn_dirent_uri.h"
+#include "svn_editor.h"
+#include "svn_error.h"
+#include "svn_wc.h"
+#include "svn_pools.h"
+
+#include "private/svn_skel.h"
+#include "private/svn_sqlite.h"
+#include "private/svn_wc_private.h"
+
+#include "wc.h"
+#include "wc_db_private.h"
+#include "conflicts.h"
+#include "workqueue.h"
+
+/*
+ * Receiver code.
+ */
+
+struct tc_editor_baton {
+ const char *src_relpath;
+ const char *dst_relpath;
+ svn_wc__db_t *db;
+ svn_wc__db_wcroot_t *wcroot;
+ svn_skel_t **work_items;
+ svn_wc_conflict_version_t *old_version;
+ svn_wc_conflict_version_t *new_version;
+ svn_wc_notify_func2_t notify_func;
+ void *notify_baton;
+ apr_pool_t *result_pool;
+};
+
+static svn_error_t *
+tc_editor_add_directory(void *baton,
+ const char *relpath,
+ const apr_array_header_t *children,
+ 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_file(void *baton,
+ const char *relpath,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents,
+ 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_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_kind_t kind,
+ 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_alter_directory(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const apr_array_header_t *children,
+ 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_alter_file(void *baton,
+ const char *dst_relpath,
+ svn_revnum_t expected_moved_here_revision,
+ apr_hash_t *props,
+ const svn_checksum_t *moved_away_checksum,
+ svn_stream_t *post_update_contents,
+ apr_pool_t *scratch_pool)
+{
+ struct tc_editor_baton *b = baton;
+ const svn_checksum_t *moved_here_checksum;
+ const char *original_repos_relpath;
+ svn_revnum_t original_revision;
+ svn_kind_t kind;
+
+ /* Get kind, revision, and checksum of the moved-here node. */
+ /*
+ * ### Currently doesn't work right if the moved-away node has been replaced.
+ * ### Need to read info from the move op-root's op-depth, not WORKING, to
+ * ### properly update shadowed nodes within multi-layer move destinations.
+ */
+ SVN_ERR(svn_wc__db_read_info_internal(NULL, &kind, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, &moved_here_checksum,
+ NULL, &original_repos_relpath, NULL,
+ &original_revision, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, b->wcroot, dst_relpath,
+ scratch_pool, scratch_pool));
+ SVN_ERR_ASSERT(original_revision == expected_moved_here_revision);
+
+ /* ### check original revision against moved-here op-root revision? */
+ if (kind != svn_kind_file)
+ return SVN_NO_ERROR;
+
+ /* ### what if checksum kind differs?*/
+ if (!svn_checksum_match(moved_away_checksum, moved_here_checksum))
+ {
+ const char *moved_to_abspath = svn_dirent_join(b->wcroot->abspath,
+ dst_relpath,
+ scratch_pool);
+ const char *pre_update_pristine_abspath;
+ const char *post_update_pristine_abspath;
+ svn_skel_t *conflict_skel;
+ enum svn_wc_merge_outcome_t merge_outcome;
+ svn_wc_notify_state_t content_state;
+ svn_wc_notify_t *notify;
+
+ /*
+ * Run a 3-way merge to update the file, using the pre-update
+ * pristine text as the merge base, the post-update pristine
+ * text as the merge-left version, and the current content of the
+ * moved-here working file as the merge-right version.
+ */
+ SVN_ERR(svn_wc__db_pristine_get_path(&pre_update_pristine_abspath,
+ b->db, moved_to_abspath,
+ moved_here_checksum,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_pristine_get_path(&post_update_pristine_abspath,
+ b->db, moved_to_abspath,
+ moved_away_checksum,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__internal_merge(b->work_items, &conflict_skel,
+ &merge_outcome, b->db,
+ pre_update_pristine_abspath,
+ post_update_pristine_abspath,
+ moved_to_abspath,
+ moved_to_abspath,
+ NULL, NULL, NULL, /* diff labels */
+ NULL, /* actual props */
+ FALSE, /* dry-run */
+ NULL, /* diff3-cmd */
+ NULL, /* merge options */
+ NULL, /* prop_diff */
+ NULL, NULL, /* cancel_func + baton */
+ b->result_pool, scratch_pool));
+
+ if (merge_outcome == svn_wc_merge_conflict)
+ {
+ svn_skel_t *work_item;
+ svn_wc_conflict_version_t *original_version;
+
+ if (conflict_skel)
+ {
+ original_version = svn_wc_conflict_version_dup(b->old_version,
+ scratch_pool);
+ original_version->path_in_repos = original_repos_relpath;
+ original_version->node_kind = svn_node_file;
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel,
+ original_version,
+ scratch_pool,
+ scratch_pool));
+ SVN_ERR(svn_wc__conflict_create_markers(&work_item, b->db,
+ moved_to_abspath,
+ conflict_skel,
+ scratch_pool,
+ scratch_pool));
+ *b->work_items = svn_wc__wq_merge(*b->work_items, work_item,
+ b->result_pool);
+ }
+ content_state = svn_wc_notify_state_conflicted;
+ }
+ else
+ {
+ svn_boolean_t is_locally_modified;
+
+ SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
+ b->db, moved_to_abspath,
+ FALSE /* exact_comparison */,
+ scratch_pool));
+ if (is_locally_modified)
+ content_state = svn_wc_notify_state_merged;
+ else
+ content_state = svn_wc_notify_state_changed;
+ }
+
+ notify = svn_wc_create_notify(moved_to_abspath,
+ svn_wc_notify_update_update,
+ scratch_pool);
+ notify->kind = svn_node_file;
+ notify->content_state = content_state;
+ notify->prop_state = svn_wc_notify_state_unknown; /* ### TODO */
+ notify->old_revision = b->old_version->peg_rev;
+ notify->revision = b->new_version->peg_rev;
+ b->notify_func(b->notify_baton, notify, scratch_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+tc_editor_alter_symlink(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props,
+ const char *target,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+}
+
+static svn_error_t *
+tc_editor_delete(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+}
+
+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)
+{
+ struct tc_editor_baton *b = baton;
+ svn_wc_notify_t *notify;
+
+ notify = svn_wc_create_notify(svn_dirent_join(b->wcroot->abspath,
+ b->dst_relpath,
+ scratch_pool),
+ svn_wc_notify_update_completed,
+ scratch_pool);
+ notify->kind = svn_node_none;
+ notify->content_state = svn_wc_notify_state_inapplicable;
+ notify->prop_state = svn_wc_notify_state_inapplicable;
+ notify->revision = b->new_version->peg_rev;
+ b->notify_func(b->notify_baton, notify, scratch_pool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+tc_editor_abort(void *baton,
+ apr_pool_t *scratch_pool)
+{
+ return SVN_NO_ERROR;
+}
+
+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.
+ */
+
+static svn_error_t *
+get_tc_info(svn_wc_operation_t *operation,
+ svn_wc_conflict_reason_t *local_change,
+ svn_wc_conflict_action_t *incoming_change,
+ svn_wc_conflict_version_t **old_version,
+ svn_wc_conflict_version_t **new_version,
+ const char *src_abspath,
+ svn_wc__db_t *db,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const apr_array_header_t *locations;
+ svn_boolean_t tree_conflicted;
+ svn_skel_t *conflict_skel;
+ svn_kind_t kind;
+
+ /* ### Check for mixed-rev src or dst? */
+
+ /* Check for tree conflict on src. */
+ SVN_ERR(svn_wc__db_read_conflict(&conflict_skel, db,
+ src_abspath,
+ scratch_pool, scratch_pool));
+ if (!conflict_skel)
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("'%s' is not in conflict"),
+ svn_dirent_local_style(src_abspath,
+ scratch_pool));
+
+ SVN_ERR(svn_wc__conflict_read_info(operation, &locations,
+ NULL, NULL, &tree_conflicted,
+ db, src_abspath,
+ conflict_skel, result_pool,
+ scratch_pool));
+ if (!tree_conflicted)
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("'%s' is not a tree-conflict victim"),
+ svn_dirent_local_style(src_abspath,
+ scratch_pool));
+ if (locations)
+ {
+ *old_version = APR_ARRAY_IDX(locations, 0,
+ svn_wc_conflict_version_t *);
+ if (locations->nelts > 1)
+ *new_version = APR_ARRAY_IDX(locations, 1,
+ svn_wc_conflict_version_t *);
+ else
+ {
+ const char *repos_root_url;
+ const char *repos_uuid;
+ const char *repos_relpath;
+ svn_revnum_t revision;
+ svn_node_kind_t node_kind;
+
+ /* Construct b->new_version from BASE info. */
+ SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision,
+ &repos_relpath, &repos_root_url,
+ &repos_uuid, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ db, src_abspath, result_pool,
+ scratch_pool));
+ node_kind = svn__node_kind_from_kind(kind);
+ *new_version = svn_wc_conflict_version_create2(repos_root_url,
+ repos_uuid,
+ repos_relpath,
+ revision,
+ node_kind,
+ scratch_pool);
+ }
+ }
+
+ SVN_ERR(svn_wc__conflict_read_tree_conflict(local_change,
+ incoming_change,
+ db, src_abspath,
+ conflict_skel, scratch_pool,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_moved_away_file(svn_editor_t *tc_editor,
+ const char *src_relpath,
+ const char *dst_relpath,
+ const char *move_dst_op_root_relpath,
+ svn_revnum_t move_dst_op_root_revision,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ apr_pool_t *scratch_pool)
+{
+ svn_kind_t kind;
+ svn_stream_t *post_update_contents;
+ const svn_checksum_t *moved_away_checksum;
+
+ /* Read post-update contents from the updated moved-away file and tell
+ * the editor to merge them into the moved-here file. */
+ SVN_ERR(svn_wc__db_read_pristine_info(NULL, &kind, NULL, NULL, NULL, NULL,
+ &moved_away_checksum, NULL, NULL, db,
+ svn_dirent_join(wcroot->abspath,
+ src_relpath,
+ scratch_pool),
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_pristine_read(&post_update_contents, NULL, db,
+ wcroot->abspath, moved_away_checksum,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_editor_alter_file(tc_editor, dst_relpath,
+ move_dst_op_root_revision,
+ NULL, /* ### TODO props */
+ moved_away_checksum,
+ post_update_contents));
+ SVN_ERR(svn_stream_close(post_update_contents));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_moved_away_dir(svn_editor_t *tc_editor,
+ const char *src_relpath,
+ const char *dst_relpath,
+ const char *move_dst_op_root_relpath,
+ svn_revnum_t move_dst_op_root_revision,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ apr_pool_t *scratch_pool)
+{
+ /* ### notify */
+
+ /* ### update prop content if changed */
+
+ /* ### update list of children if changed */
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_moved_away_subtree(svn_editor_t *tc_editor,
+ const char *src_relpath,
+ const char *dst_relpath,
+ const char *move_dst_op_root_relpath,
+ svn_revnum_t move_dst_op_root_revision,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ apr_pool_t *scratch_pool)
+{
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool;
+ int i;
+
+ SVN_ERR(update_moved_away_dir(tc_editor, src_relpath, dst_relpath,
+ move_dst_op_root_relpath,
+ move_dst_op_root_revision,
+ db, wcroot, scratch_pool));
+
+ SVN_ERR(svn_wc__db_base_get_children(&children, db,
+ svn_dirent_join(wcroot->abspath,
+ src_relpath,
+ scratch_pool),
+ scratch_pool, scratch_pool));
+ iterpool = svn_pool_create(scratch_pool);
+ for (i = 0; i < children->nelts; i++)
+ {
+ const char *child_src_relpath;
+ svn_kind_t child_kind;
+ const char *child_dst_op_root_relpath;
+ const char *child_dst_relpath;
+
+ svn_pool_clear(iterpool);
+
+ child_src_relpath = svn_relpath_join(src_relpath,
+ APR_ARRAY_IDX(children, i,
+ const char *),
+ iterpool);
+
+ /* Is this child part of our move operation? */
+ /* ### need to handle children which were newly added or removed
+ * ### during the update */
+ SVN_ERR(svn_wc__db_scan_deletion_internal(NULL, &child_dst_relpath, NULL,
+ &child_dst_op_root_relpath,
+ wcroot, child_src_relpath,
+ iterpool, iterpool));
+ if (child_dst_op_root_relpath == NULL ||
+ strcmp(child_dst_op_root_relpath, move_dst_op_root_relpath) != 0)
+ continue;
+
+ SVN_ERR(svn_wc__db_base_get_info_internal(NULL, &child_kind,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ wcroot, child_src_relpath,
+ iterpool, iterpool));
+
+ if (child_kind == svn_kind_file || child_kind == svn_kind_symlink)
+ SVN_ERR(update_moved_away_file(tc_editor, child_src_relpath,
+ child_dst_relpath,
+ move_dst_op_root_relpath,
+ move_dst_op_root_revision,
+ db, wcroot, iterpool));
+ else if (child_kind == svn_kind_dir)
+ SVN_ERR(update_moved_away_subtree(tc_editor, child_src_relpath,
+ child_dst_relpath,
+ move_dst_op_root_relpath,
+ move_dst_op_root_revision,
+ db, wcroot, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+drive_tree_conflict_editor(svn_editor_t *tc_editor,
+ const char *src_relpath,
+ const char *dst_relpath,
+ svn_wc_operation_t operation,
+ svn_wc_conflict_reason_t local_change,
+ svn_wc_conflict_action_t incoming_change,
+ svn_wc_conflict_version_t *old_version,
+ svn_wc_conflict_version_t *new_version,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ /*
+ * Refuse to auto-resolve unsupported tree conflicts.
+ */
+ /* ### Only handle conflicts created by update/switch operations for now. */
+ if (operation != svn_wc_operation_update &&
+ operation != svn_wc_operation_switch)
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("Cannot auto-resolve tree-conflict on '%s'"),
+ svn_dirent_local_style(
+ svn_dirent_join(wcroot->abspath,
+ src_relpath, scratch_pool),
+ scratch_pool));
+
+ /*
+ * Drive the TC editor to transfer incoming changes from the move source
+ * to the move destination.
+ *
+ * The pre-update tree is within dst at the op-depth of the move's op-root.
+ * The post-update base tree is within src at op-depth zero.
+ *
+ * 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.
+ */
+ if (old_version->node_kind == svn_node_file)
+ SVN_ERR(update_moved_away_file(tc_editor, src_relpath, dst_relpath,
+ dst_relpath, old_version->peg_rev,
+ db, wcroot, scratch_pool));
+ else if (old_version->node_kind == svn_node_dir)
+ SVN_ERR(update_moved_away_subtree(tc_editor, src_relpath, dst_relpath,
+ dst_relpath, old_version->peg_rev,
+ db, wcroot, scratch_pool));
+
+ SVN_ERR(svn_editor_complete(tc_editor));
+
+ return SVN_NO_ERROR;
+}
+
+struct update_moved_away_conflict_victim_baton {
+ svn_skel_t **work_items;
+ const char *victim_relpath;
+ svn_wc_operation_t operation;
+ svn_wc_conflict_reason_t local_change;
+ svn_wc_conflict_action_t incoming_change;
+ svn_wc_conflict_version_t *old_version;
+ svn_wc_conflict_version_t *new_version;
+ svn_wc__db_t *db;
+ svn_wc_notify_func2_t notify_func;
+ void *notify_baton;
+ svn_cancel_func_t cancel_func;
+ void *cancel_baton;
+ apr_pool_t *result_pool;
+};
+
+/* An implementation of svn_wc__db_txn_callback_t. */
+static svn_error_t *
+update_moved_away_conflict_victim(void *baton,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *victim_relpath,
+ apr_pool_t *scratch_pool)
+{
+ struct update_moved_away_conflict_victim_baton *b = baton;
+ svn_editor_t *tc_editor;
+ struct tc_editor_baton *tc_editor_baton;
+
+ /* ### assumes wc write lock already held */
+
+ /* Construct editor baton. */
+ tc_editor_baton = apr_pcalloc(scratch_pool, sizeof(*tc_editor_baton));
+ tc_editor_baton->src_relpath = b->victim_relpath;
+ SVN_ERR(svn_wc__db_scan_deletion_internal(NULL,
+ &tc_editor_baton->dst_relpath,
+ NULL, NULL, wcroot,
+ tc_editor_baton->src_relpath,
+ scratch_pool, scratch_pool));
+ if (tc_editor_baton->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(
+ svn_dirent_join(wcroot->abspath,
+ b->victim_relpath,
+ scratch_pool),
+ scratch_pool));
+ tc_editor_baton->old_version= b->old_version;
+ tc_editor_baton->new_version= b->new_version;
+ tc_editor_baton->db = b->db;
+ tc_editor_baton->wcroot = wcroot;
+ tc_editor_baton->work_items = b->work_items;
+ tc_editor_baton->notify_func = b->notify_func;
+ tc_editor_baton->notify_baton = b->notify_baton;
+ tc_editor_baton->result_pool = b->result_pool;
+
+ /* Create the editor... */
+ SVN_ERR(svn_editor_create(&tc_editor, tc_editor_baton,
+ b->cancel_func, b->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,
+ tc_editor_baton->src_relpath,
+ tc_editor_baton->dst_relpath,
+ b->operation,
+ b->local_change, b->incoming_change,
+ tc_editor_baton->old_version,
+ tc_editor_baton->new_version,
+ b->db, wcroot,
+ b->cancel_func, b->cancel_baton,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__db_update_moved_away_conflict_victim(svn_skel_t **work_items,
+ const char *victim_abspath,
+ svn_wc__db_t *db,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct update_moved_away_conflict_victim_baton b;
+ svn_wc__db_wcroot_t *wcroot;
+ const char *local_relpath;
+ svn_wc_operation_t operation;
+ svn_wc_conflict_reason_t local_change;
+ svn_wc_conflict_action_t incoming_change;
+ svn_wc_conflict_version_t *old_version;
+ svn_wc_conflict_version_t *new_version;
+
+ SVN_ERR(get_tc_info(&operation, &local_change, &incoming_change,
+ &old_version, &new_version,
+ victim_abspath, db, scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+ db, victim_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ b.work_items = work_items;
+ b.victim_relpath = local_relpath;
+ b.operation = operation;
+ b.local_change = local_change;
+ b.incoming_change = incoming_change;
+ b.old_version = old_version;
+ b.new_version = new_version;
+ b.db = db;
+ b.notify_func = notify_func;
+ b.notify_baton = notify_baton;
+ b.cancel_func = cancel_func;
+ b.cancel_baton = cancel_baton;
+ b.result_pool = result_pool;
+
+ SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath,
+ update_moved_away_conflict_victim, &b,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_util.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_util.c Sat Nov 24 20:29:11 2012
@@ -80,10 +80,10 @@ svn_wc__db_util_fetch_wc_id(apr_int64_t
/* An SQLite application defined function that allows SQL queries to
use "relpath_depth(local_relpath)". */
static svn_error_t *
-relpath_depth(svn_sqlite__context_t *sctx,
- int argc,
- svn_sqlite__value_t *values[],
- apr_pool_t *scratch_pool)
+relpath_depth_sqlite(svn_sqlite__context_t *sctx,
+ int argc,
+ svn_sqlite__value_t *values[],
+ apr_pool_t *scratch_pool)
{
const char *path = NULL;
apr_int64_t depth;
@@ -114,6 +114,7 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
const char *dir_abspath,
const char *sdb_fname,
svn_sqlite__mode_t smode,
+ svn_boolean_t exclusive,
const char *const *my_statements,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -140,8 +141,11 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
my_statements ? my_statements : statements,
0, NULL, result_pool, scratch_pool));
+ if (exclusive)
+ SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_PRAGMA_LOCKING_MODE));
+
SVN_ERR(svn_sqlite__create_scalar_function(*sdb, "relpath_depth", 1,
- relpath_depth, NULL));
+ relpath_depth_sqlite, NULL));
return SVN_NO_ERROR;
}
Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_wcroot.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/wc_db_wcroot.c Sat Nov 24 20:29:11 2012
@@ -26,6 +26,8 @@
#include <assert.h>
#include "svn_dirent_uri.h"
+#include "svn_path.h"
+#include "svn_version.h"
#include "wc.h"
#include "adm_files.h"
@@ -182,7 +184,7 @@ close_wcroot(void *data)
svn_error_clear(err_pdb);
return result;
}
-
+
if (err_sdb)
{
apr_status_t result = err_sdb->apr_err;
@@ -196,7 +198,7 @@ close_wcroot(void *data)
svn_error_t *
svn_wc__db_open(svn_wc__db_t **db,
- const svn_config_t *config,
+ svn_config_t *config,
svn_boolean_t auto_upgrade,
svn_boolean_t enforce_empty_wq,
apr_pool_t *result_pool,
@@ -305,9 +307,24 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
}
/* Auto-upgrade the SDB if possible. */
- if (format < SVN_WC__VERSION && auto_upgrade)
- SVN_ERR(svn_wc__upgrade_sdb(&format, wcroot_abspath, sdb, format,
- scratch_pool));
+ if (format < SVN_WC__VERSION)
+ {
+ if (auto_upgrade)
+ {
+ if (format >= SVN_WC__WC_NG_VERSION)
+ SVN_ERR(svn_wc__upgrade_sdb(&format, wcroot_abspath, sdb, format,
+ scratch_pool));
+ }
+ else
+ return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
+ _("The working copy at '%s'\nis too old "
+ "(format %d) to work with client version "
+ "'%s' (expects format %d). You need to "
+ "upgrade the working copy first.\n"),
+ svn_dirent_local_style(wcroot_abspath,
+ scratch_pool), format, SVN_VERSION,
+ SVN_WC__VERSION);
+ }
*wcroot = apr_palloc(result_pool, sizeof(**wcroot));
@@ -366,6 +383,40 @@ compute_relpath(const svn_wc__db_wcroot_
}
+/* Return in *LINK_TARGET_ABSPATH the absolute path the symlink at
+ * LOCAL_ABSPATH is pointing to. Perform all allocations in POOL. */
+static svn_error_t *
+read_link_target(const char **link_target_abspath,
+ const char *local_abspath,
+ apr_pool_t *pool)
+{
+ svn_string_t *link_target;
+ const char *canon_link_target;
+
+ SVN_ERR(svn_io_read_link(&link_target, local_abspath, pool));
+ if (link_target->len == 0)
+ return svn_error_createf(SVN_ERR_WC_NOT_SYMLINK, NULL,
+ _("The symlink at '%s' points nowhere"),
+ svn_dirent_local_style(local_abspath, pool));
+
+ canon_link_target = svn_dirent_canonicalize(link_target->data, pool);
+
+ /* Treat relative symlinks as relative to LOCAL_ABSPATH's parent. */
+ if (!svn_dirent_is_absolute(canon_link_target))
+ canon_link_target = svn_dirent_join(svn_dirent_dirname(local_abspath,
+ pool),
+ canon_link_target, pool);
+
+ /* Collapse any .. in the symlink part of the path. */
+ if (svn_path_is_backpath_present(canon_link_target))
+ SVN_ERR(svn_dirent_get_absolute(link_target_abspath, canon_link_target,
+ pool));
+ else
+ *link_target_abspath = canon_link_target;
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_wc__db_wcroot_parse_local_abspath(svn_wc__db_wcroot_t **wcroot,
const char **local_relpath,
@@ -487,6 +538,18 @@ svn_wc__db_wcroot_parse_local_abspath(sv
if (adm_subdir_kind == svn_node_dir)
{
+ svn_boolean_t sqlite_exclusive = FALSE;
+
+ err = svn_config_get_bool(db->config, &sqlite_exclusive,
+ SVN_CONFIG_SECTION_WORKING_COPY,
+ SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
+ FALSE);
+ if (err)
+ {
+ svn_error_clear(err);
+ sqlite_exclusive = FALSE;
+ }
+
/* We always open the database in read/write mode. If the database
isn't writable in the filesystem, SQLite will internally open
it as read-only, and we'll get an error if we try to do a write
@@ -496,7 +559,8 @@ svn_wc__db_wcroot_parse_local_abspath(sv
we're caching database handles, it make sense to be as permissive
as the filesystem allows. */
err = svn_wc__db_util_open_db(&sdb, local_abspath, SDB_FILE,
- svn_sqlite__mode_readwrite, NULL,
+ svn_sqlite__mode_readwrite,
+ sqlite_exclusive, NULL,
db->state_pool, scratch_pool);
if (err == NULL)
{
@@ -563,6 +627,8 @@ svn_wc__db_wcroot_parse_local_abspath(sv
if (found_wcroot)
break;
+ SVN_ERR(read_link_target(&local_abspath, local_abspath,
+ scratch_pool));
try_symlink_as_dir:
kind = svn_kind_dir;
moved_upwards = FALSE;
@@ -619,32 +685,45 @@ try_symlink_as_dir:
inside the wcroot, but we know the abspath is this directory
(ie. where we found it). */
- SVN_ERR(svn_wc__db_pdh_create_wcroot(wcroot,
+ err = svn_wc__db_pdh_create_wcroot(wcroot,
apr_pstrdup(db->state_pool, local_abspath),
sdb, pdb, wc_id, FORMAT_FROM_SDB,
db->auto_upgrade, db->enforce_empty_wq,
- db->state_pool, scratch_pool));
+ db->state_pool, scratch_pool);
+ if (err && (err->apr_err == SVN_ERR_WC_UNSUPPORTED_FORMAT ||
+ err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED) &&
+ kind == svn_kind_symlink)
+ {
+ /* We found an unsupported WC after traversing upwards from a
+ * symlink. Fall through to code below to check if the symlink
+ * points at a supported WC. */
+ svn_error_clear(err);
+ *wcroot = NULL;
+ }
+ else
+ SVN_ERR(err);
}
else
{
/* We found a wc-1 working copy directory. */
SVN_ERR(svn_wc__db_pdh_create_wcroot(wcroot,
apr_pstrdup(db->state_pool, local_abspath),
- NULL, NULL, UNKNOWN_WC_ID, wc_format,
+ NULL, UNKNOWN_WC_ID, wc_format,
db->auto_upgrade, db->enforce_empty_wq,
db->state_pool, scratch_pool));
}
- {
- const char *dir_relpath;
+ if (*wcroot)
+ {
+ const char *dir_relpath;
- /* The subdirectory's relpath is easily computed relative to the
- wcroot that we just found. */
- dir_relpath = compute_relpath(*wcroot, local_dir_abspath, NULL);
-
- /* And the result local_relpath may include a filename. */
- *local_relpath = svn_relpath_join(dir_relpath, build_relpath, result_pool);
- }
+ /* The subdirectory's relpath is easily computed relative to the
+ wcroot that we just found. */
+ dir_relpath = compute_relpath(*wcroot, local_dir_abspath, NULL);
+
+ /* And the result local_relpath may include a filename. */
+ *local_relpath = svn_relpath_join(dir_relpath, build_relpath, result_pool);
+ }
if (kind == svn_kind_symlink)
{
@@ -658,33 +737,38 @@ try_symlink_as_dir:
* points to a directory, try to find a wcroot in that directory
* instead. */
- err = svn_wc__db_read_info_internal(&status, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &conflicted, NULL, NULL, NULL,
- NULL, NULL, NULL,
- *wcroot, *local_relpath,
- scratch_pool, scratch_pool);
- if (err)
+ if (*wcroot)
{
- if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
- && !SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
- return svn_error_trace(err);
+ err = svn_wc__db_read_info_internal(&status, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, &conflicted,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, *wcroot, *local_relpath,
+ scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
+ && !SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
+ return svn_error_trace(err);
- svn_error_clear(err);
- retry_if_dir = TRUE; /* The symlink is unversioned. */
+ svn_error_clear(err);
+ retry_if_dir = TRUE; /* The symlink is unversioned. */
+ }
+ else
+ {
+ /* The symlink is versioned, or obstructs a versioned node.
+ * Ignore non-conflicted not-present/excluded nodes.
+ * This allows the symlink to redirect the wcroot query to a
+ * directory, regardless of 'invisible' nodes in this WC. */
+ retry_if_dir = ((status == svn_wc__db_status_not_present ||
+ status == svn_wc__db_status_excluded ||
+ status == svn_wc__db_status_server_excluded)
+ && !conflicted);
+ }
}
else
- {
- /* The symlink is versioned, or obstructs a versioned node.
- * Ignore non-conflicted not-present/excluded nodes.
- * This allows the symlink to redirect the wcroot query to a
- * directory, regardless of 'invisible' nodes in this WC. */
- retry_if_dir = ((status == svn_wc__db_status_not_present ||
- status == svn_wc__db_status_excluded ||
- status == svn_wc__db_status_server_excluded)
- && !conflicted);
- }
+ retry_if_dir = TRUE;
if (retry_if_dir)
{
@@ -695,7 +779,11 @@ try_symlink_as_dir:
scratch_pool));
if (resolved_kind == svn_node_dir)
{
- local_abspath = original_abspath;
+ SVN_ERR(read_link_target(&local_abspath, original_abspath,
+ scratch_pool));
+ /* This handle was opened in this function but is not going
+ to be used further so close it. */
+ SVN_ERR(svn_sqlite__close(sdb));
goto try_symlink_as_dir;
}
}
Modified: subversion/branches/compressed-pristines/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_authz_svn/mod_authz_svn.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/compressed-pristines/subversion/mod_authz_svn/mod_authz_svn.c Sat Nov 24 20:29:11 2012
@@ -44,6 +44,7 @@
#include "svn_config.h"
#include "svn_string.h"
#include "svn_repos.h"
+#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "private/svn_fspath.h"
@@ -164,7 +165,8 @@ static const command_rec authz_svn_cmds[
* Get the, possibly cached, svn_authz_t for this request.
*/
static svn_authz_t *
-get_access_conf(request_rec *r, authz_svn_config_rec *conf)
+get_access_conf(request_rec *r, authz_svn_config_rec *conf,
+ apr_pool_t *scratch_pool)
{
const char *cache_key = NULL;
const char *access_file;
@@ -182,7 +184,7 @@ get_access_conf(request_rec *r, authz_sv
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "%s", dav_err->desc);
return NULL;
}
- access_file = svn_dirent_join_many(r->pool, repos_path, "conf",
+ access_file = svn_dirent_join_many(scratch_pool, repos_path, "conf",
conf->repo_relative_access_file,
NULL);
}
@@ -194,7 +196,7 @@ get_access_conf(request_rec *r, authz_sv
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"Path to authz file is %s", access_file);
- cache_key = apr_pstrcat(r->pool, "mod_authz_svn:",
+ cache_key = apr_pstrcat(scratch_pool, "mod_authz_svn:",
access_file, (char *)NULL);
apr_pool_userdata_get(&user_data, cache_key, r->connection->pool);
access_conf = user_data;
@@ -243,12 +245,13 @@ convert_case(char *text, svn_boolean_t t
/* Return the username to authorize, with case-conversion performed if
CONF->force_username_case is set. */
static char *
-get_username_to_authorize(request_rec *r, authz_svn_config_rec *conf)
+get_username_to_authorize(request_rec *r, authz_svn_config_rec *conf,
+ apr_pool_t *pool)
{
char *username_to_authorize = r->user;
if (username_to_authorize && conf->force_username_case)
{
- username_to_authorize = apr_pstrdup(r->pool, r->user);
+ username_to_authorize = apr_pstrdup(pool, r->user);
convert_case(username_to_authorize,
strcasecmp(conf->force_username_case, "upper") == 0);
}
@@ -283,7 +286,8 @@ req_check_access(request_rec *r,
svn_authz_t *access_conf = NULL;
svn_error_t *svn_err;
char errbuf[256];
- const char *username_to_authorize = get_username_to_authorize(r, conf);
+ const char *username_to_authorize = get_username_to_authorize(r, conf,
+ r->pool);
switch (r->method_number)
{
@@ -419,7 +423,7 @@ req_check_access(request_rec *r,
}
/* Retrieve/cache authorization file */
- access_conf = get_access_conf(r,conf);
+ access_conf = get_access_conf(r,conf, r->pool);
if (access_conf == NULL)
return DECLINED;
@@ -577,14 +581,13 @@ log_access_verdict(LOG_ARGS_SIGNATURE,
}
/*
- * This function is used as a provider to allow mod_dav_svn to bypass the
- * generation of an apache request when checking GET access from
- * "mod_dav_svn/authz.c" .
+ * Implementation of subreq_bypass with scratch_pool parameter.
*/
static int
-subreq_bypass(request_rec *r,
- const char *repos_path,
- const char *repos_name)
+subreq_bypass2(request_rec *r,
+ const char *repos_path,
+ const char *repos_name,
+ apr_pool_t *scratch_pool)
{
svn_error_t *svn_err = NULL;
svn_authz_t *access_conf = NULL;
@@ -595,7 +598,7 @@ subreq_bypass(request_rec *r,
conf = ap_get_module_config(r->per_dir_config,
&authz_svn_module);
- username_to_authorize = get_username_to_authorize(r, conf);
+ username_to_authorize = get_username_to_authorize(r, conf, scratch_pool);
/* If configured properly, this should never be true, but just in case. */
if (!conf->anonymous
@@ -606,7 +609,7 @@ subreq_bypass(request_rec *r,
}
/* Retrieve authorization file */
- access_conf = get_access_conf(r, conf);
+ access_conf = get_access_conf(r, conf, scratch_pool);
if (access_conf == NULL)
return HTTP_FORBIDDEN;
@@ -620,7 +623,7 @@ subreq_bypass(request_rec *r,
username_to_authorize,
svn_authz_none|svn_authz_read,
&authz_access_granted,
- r->pool);
+ scratch_pool);
if (svn_err)
{
ap_log_rerror(APLOG_MARK, APLOG_ERR,
@@ -650,6 +653,26 @@ subreq_bypass(request_rec *r,
}
/*
+ * This function is used as a provider to allow mod_dav_svn to bypass the
+ * generation of an apache request when checking GET access from
+ * "mod_dav_svn/authz.c" .
+ */
+static int
+subreq_bypass(request_rec *r,
+ const char *repos_path,
+ const char *repos_name)
+{
+ int status;
+ apr_pool_t *scratch_pool;
+
+ scratch_pool = svn_pool_create(r->pool);
+ status = subreq_bypass2(r, repos_path, repos_name, scratch_pool);
+ svn_pool_destroy(scratch_pool);
+
+ return status;
+}
+
+/*
* Hooks
*/
Modified: subversion/branches/compressed-pristines/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_dav_svn/activity.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/compressed-pristines/subversion/mod_dav_svn/activity.c Sat Nov 24 20:29:11 2012
@@ -240,16 +240,21 @@ dav_svn__store_activity(const dav_svn_re
dav_error *
dav_svn__create_txn(const dav_svn_repos *repos,
const char **ptxn_name,
+ apr_hash_t *revprops,
apr_pool_t *pool)
{
svn_revnum_t rev;
svn_fs_txn_t *txn;
svn_error_t *serr;
- apr_hash_t *revprop_table = apr_hash_make(pool);
+
+ if (! revprops)
+ {
+ revprops = apr_hash_make(pool);
+ }
if (repos->username)
{
- apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING,
+ apr_hash_set(revprops, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING,
svn_string_create(repos->username, pool));
}
@@ -262,8 +267,7 @@ dav_svn__create_txn(const dav_svn_repos
}
serr = svn_repos_fs_begin_txn_for_commit2(&txn, repos->repos, rev,
- revprop_table,
- repos->pool);
+ revprops, repos->pool);
if (serr != NULL)
{
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
Modified: subversion/branches/compressed-pristines/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_dav_svn/dav_svn.h?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/compressed-pristines/subversion/mod_dav_svn/dav_svn.h Sat Nov 24 20:29:11 2012
@@ -304,9 +304,6 @@ svn_boolean_t dav_svn__get_autoversionin
/* for the repository referred to by this request, are bulk updates allowed? */
svn_boolean_t dav_svn__get_bulk_updates_flag(request_rec *r);
-/* for the repository referred to by this request, should httpv2 be advertised? */
-svn_boolean_t dav_svn__get_v2_protocol_flag(request_rec *r);
-
/* for the repository referred to by this request, are subrequests active? */
svn_boolean_t dav_svn__get_pathauthz_flag(request_rec *r);
@@ -328,6 +325,17 @@ authz_svn__subreq_bypass_func_t dav_svn_
SVNParentPath allowed? */
svn_boolean_t dav_svn__get_list_parentpath_flag(request_rec *r);
+/* For the repository referred to by this request, should HTTPv2
+ protocol support be advertised? Note that this also takes into
+ account the support level expected of based on the specified
+ master server version (if provided via SVNMasterVersion). */
+svn_boolean_t dav_svn__check_httpv2_support(request_rec *r);
+
+/* For the repository referred to by this request, should ephemeral
+ txnprop support be advertised? */
+svn_boolean_t dav_svn__check_ephemeral_txnprops_support(request_rec *r);
+
+
/* SPECIAL URI
@@ -376,6 +384,11 @@ const char *dav_svn__get_xslt_uri(reques
/* ### Is this assumed to be URI-encoded? */
const char *dav_svn__get_master_uri(request_rec *r);
+/* Return the version of the master server (used for mirroring) iff a
+ master URI is in place for this location; otherwise, return NULL.
+ Comes from the <SVNMasterVersion> directive. */
+svn_version_t *dav_svn__get_master_version(request_rec *r);
+
/* Return the disk path to the activities db.
Comes from the <SVNActivitiesDB> directive. */
const char *dav_svn__get_activities_db(request_rec *r);
@@ -386,10 +399,10 @@ const char *dav_svn__get_activities_db(r
const char *dav_svn__get_root_dir(request_rec *r);
/* Return the data compression level to be used over the wire. */
-int dav_svn__get_compression_level(void);
+int dav_svn__get_compression_level(request_rec *r);
/* Return the hook script environment parsed from the configuration. */
-apr_hash_t *dav_svn__get_hooks_env(request_rec *r);
+const char *dav_svn__get_hooks_env(request_rec *r);
/** For HTTP protocol v2, these are the new URIs and URI stubs
returned to the client in our OPTIONS response. They all depend
@@ -420,10 +433,17 @@ const char *dav_svn__get_vtxn_root_stub(
/*** activity.c ***/
/* Create a new transaction based on HEAD in REPOS, setting *PTXN_NAME
- to the name of that transaction. Use POOL for allocations. */
+ to the name of that transaction. REVPROPS is an optional hash of
+ const char * property names and const svn_string_t * values which
+ will be set as transactions properties on the transaction this
+ function creates. Use POOL for allocations.
+
+ NOTE: This function will overwrite the svn:author property, if
+ any, found in REVPROPS. */
dav_error *
dav_svn__create_txn(const dav_svn_repos *repos,
const char **ptxn_name,
+ apr_hash_t *revprops,
apr_pool_t *pool);
/* If it exists, abort the transaction named TXN_NAME from REPOS. Use
@@ -620,6 +640,7 @@ static const dav_report_elem dav_svn__re
{ SVN_XML_NAMESPACE, "replay-report" },
{ SVN_XML_NAMESPACE, "get-deleted-rev-report" },
{ SVN_XML_NAMESPACE, SVN_DAV__MERGEINFO_REPORT },
+ { SVN_XML_NAMESPACE, SVN_DAV__INHERITED_PROPS_REPORT },
{ NULL, NULL },
};
@@ -667,23 +688,22 @@ dav_svn__get_deleted_rev_report(const da
const apr_xml_doc *doc,
ap_filter_t *output);
+dav_error *
+dav_svn__get_inherited_props_report(const dav_resource *resource,
+ const apr_xml_doc *doc,
+ ap_filter_t *output);
/*** posts/ ***/
-/* The list of Subversion's custom POSTs. */
-/* ### TODO: Populate this list and transmit its contents in the
- ### OPTIONS response.
-static const char * dav_svn__posts_list[] = {
- "create-txn",
- NULL
-};
-*/
-
/* The various POST handlers, defined in posts/, and used by repos.c. */
dav_error *
dav_svn__post_create_txn(const dav_resource *resource,
svn_skel_t *request_skel,
ap_filter_t *output);
+dav_error *
+dav_svn__post_create_txn_with_props(const dav_resource *resource,
+ svn_skel_t *request_skel,
+ ap_filter_t *output);
/*** authz.c ***/
@@ -739,7 +759,11 @@ dav_svn__authz_read_func(dav_svn__authz_
processing. See dav_new_error_tag for parameter documentation.
Note that DESC may be null (it's hard to track this down from
dav_new_error_tag()'s documentation, but see the dav_error type,
- which says that its desc field may be NULL). */
+ 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.
+*/
dav_error *
dav_svn__new_error_tag(apr_pool_t *pool,
int status,
@@ -754,7 +778,11 @@ dav_svn__new_error_tag(apr_pool_t *pool,
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). */
+ 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.
+*/
dav_error *
dav_svn__new_error(apr_pool_t *pool,
int status,
Modified: subversion/branches/compressed-pristines/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_dav_svn/deadprops.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/compressed-pristines/subversion/mod_dav_svn/deadprops.c Sat Nov 24 20:29:11 2012
@@ -1,5 +1,7 @@
/*
- * deadprops.c: mod_dav_svn dead property provider functions for Subversion
+ * deadprops.c: mod_dav_svn provider functions for "dead properties"
+ * (properties implemented by Subversion or its users,
+ * not as part of the WebDAV specification).
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -512,10 +514,6 @@ db_store(dav_db *db,
/* ### namespace check? */
if (elem->first_child && !strcmp(elem->first_child->name, SVN_DAV__OLD_VALUE))
{
- const char *propname;
-
- get_repos_propname(db, name, &propname);
-
/* Parse OLD_PROPVAL. */
old_propval = svn_string_create(dav_xml_get_cdata(elem->first_child, pool,
0 /* strip_white */),
Modified: subversion/branches/compressed-pristines/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_dav_svn/liveprops.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/compressed-pristines/subversion/mod_dav_svn/liveprops.c Sat Nov 24 20:29:11 2012
@@ -1,5 +1,7 @@
/*
- * liveprops.c: mod_dav_svn live property provider functions for Subversion
+ * liveprops.c: mod_dav_svn provider functions for "live properties"
+ * (properties implemented by the WebDAV specification
+ * itself, not unique to Subversion or its users).
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -275,8 +277,8 @@ insert_prop_internal(const dav_resource
int propid,
dav_prop_insert what,
apr_text_header *phdr,
- apr_pool_t *scratch_pool,
- apr_pool_t *result_pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
const char *value = NULL;
const char *s;
@@ -820,7 +822,7 @@ insert_prop(const dav_resource *resource
scratch_pool = svn_pool_create(result_pool);
rv = insert_prop_internal(resource, propid, what, phdr,
- scratch_pool, result_pool);
+ result_pool, scratch_pool);
svn_pool_destroy(scratch_pool);
return rv;
@@ -958,7 +960,7 @@ dav_svn__insert_all_liveprops(request_re
{
svn_pool_clear(iterpool);
(void) insert_prop_internal(resource, spec->propid, what, phdr,
- iterpool, resource->pool);
+ resource->pool, iterpool);
}
svn_pool_destroy(iterpool);
Modified: subversion/branches/compressed-pristines/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_dav_svn/mod_dav_svn.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/compressed-pristines/subversion/mod_dav_svn/mod_dav_svn.c Sat Nov 24 20:29:11 2012
@@ -42,6 +42,7 @@
#include "mod_dav_svn.h"
#include "private/svn_fspath.h"
+#include "private/svn_subr_private.h"
#include "dav_svn.h"
#include "mod_authz_svn.h"
@@ -59,6 +60,12 @@
typedef struct server_conf_t {
const char *special_uri;
svn_boolean_t use_utf8;
+
+ /* The compression level we will pass to svn_txdelta_to_svndiff3()
+ * for wire-compression. Negative value used to specify default
+ compression level. */
+ int compression_level;
+
} server_conf_t;
@@ -92,11 +99,12 @@ typedef struct dir_conf_t {
enum conf_flag list_parentpath; /* whether to allow GET of parentpath */
const char *root_dir; /* our top-level directory */
const char *master_uri; /* URI to the master SVN repos */
+ svn_version_t *master_version; /* version of master server */
const char *activities_db; /* path to activities database(s) */
enum conf_flag txdelta_cache; /* whether to enable txdelta caching */
enum conf_flag fulltext_cache; /* whether to enable fulltext caching */
enum conf_flag revprop_cache; /* whether to enable revprop caching */
- apr_hash_t *hooks_env; /* environment for hook scripts */
+ const char *hooks_env; /* path to hook script env config file */
} dir_conf_t;
@@ -109,10 +117,6 @@ extern module AP_MODULE_DECLARE_DATA dav
/* The authz_svn provider for bypassing path authz. */
static authz_svn__subreq_bypass_func_t pathauthz_bypass_func = NULL;
-/* The compression level we will pass to svn_txdelta_to_svndiff3()
- * for wire-compression */
-static int svn__compression_level = SVN_DELTA_COMPRESSION_LEVEL_DEFAULT;
-
static int
init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
@@ -163,7 +167,11 @@ init_dso(apr_pool_t *pconf, apr_pool_t *
static void *
create_server_config(apr_pool_t *p, server_rec *s)
{
- return apr_pcalloc(p, sizeof(server_conf_t));
+ server_conf_t *conf = apr_pcalloc(p, sizeof(server_conf_t));
+
+ conf->compression_level = -1;
+
+ return conf;
}
@@ -179,6 +187,17 @@ merge_server_config(apr_pool_t *p, void
newconf->special_uri = INHERIT_VALUE(parent, child, special_uri);
+ if (child->compression_level < 0)
+ {
+ /* Inherit compression level from parent if not configured for this
+ VirtualHost. */
+ newconf->compression_level = parent->compression_level;
+ }
+ else
+ {
+ newconf->compression_level = child->compression_level;
+ }
+
return newconf;
}
@@ -214,6 +233,7 @@ merge_dir_config(apr_pool_t *p, void *ba
newconf->fs_path = INHERIT_VALUE(parent, child, fs_path);
newconf->master_uri = INHERIT_VALUE(parent, child, master_uri);
+ newconf->master_version = INHERIT_VALUE(parent, child, master_version);
newconf->activities_db = INHERIT_VALUE(parent, child, activities_db);
newconf->repo_name = INHERIT_VALUE(parent, child, repo_name);
newconf->xslt_uri = INHERIT_VALUE(parent, child, xslt_uri);
@@ -282,6 +302,25 @@ SVNMasterURI_cmd(cmd_parms *cmd, void *c
static const char *
+SVNMasterVersion_cmd(cmd_parms *cmd, void *config, const char *arg1)
+{
+ dir_conf_t *conf = config;
+ svn_error_t *err;
+ svn_version_t *version;
+
+ err = svn_version__parse_version_string(&version, arg1, cmd->pool);
+ if (err)
+ {
+ svn_error_clear(err);
+ return "Malformed master server version string.";
+ }
+
+ conf->master_version = version;
+ return NULL;
+}
+
+
+static const char *
SVNActivitiesDB_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
dir_conf_t *conf = config;
@@ -513,6 +552,7 @@ SVNInMemoryCacheSize_cmd(cmd_parms *cmd,
static const char *
SVNCompressionLevel_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
+ server_conf_t *conf;
int value = 0;
svn_error_t *err = svn_cstring_atoi(&value, arg1);
if (err)
@@ -530,7 +570,9 @@ SVNCompressionLevel_cmd(cmd_parms *cmd,
(int)SVN_DELTA_COMPRESSION_LEVEL_NONE,
(int)SVN_DELTA_COMPRESSION_LEVEL_MAX);
- svn__compression_level = value;
+ conf = ap_get_module_config(cmd->server->module_config,
+ &dav_svn_module);
+ conf->compression_level = value;
return NULL;
}
@@ -550,43 +592,9 @@ SVNUseUTF8_cmd(cmd_parms *cmd, void *con
static const char *
SVNHooksEnv_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
- apr_array_header_t *var;
-
- var = svn_cstring_split(arg1, "=", TRUE, cmd->pool);
- if (var && var->nelts >= 2)
- {
- dir_conf_t *conf = config;
- const char *name;
- const char *val;
-
- if (! conf->hooks_env)
- conf->hooks_env = apr_hash_make(cmd->pool);
-
- name = apr_pstrdup(apr_hash_pool_get(conf->hooks_env),
- APR_ARRAY_IDX(var, 0, const char *));
-
- /* Special case for values which contain '='. */
- if (var->nelts > 2)
- {
- svn_stringbuf_t *buf;
- int i;
-
- buf = svn_stringbuf_create(APR_ARRAY_IDX(var, 1, const char *),
- cmd->pool);
- for (i = 2; i < var->nelts; i++)
- {
- svn_stringbuf_appendbyte(buf, '=');
- svn_stringbuf_appendcstr(buf, APR_ARRAY_IDX(var, i, const char *));
- }
+ dir_conf_t *conf = config;
- val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env), buf->data);
- }
- else
- val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env),
- APR_ARRAY_IDX(var, 1, const char *));
-
- apr_hash_set(conf->hooks_env, name, APR_HASH_KEY_STRING, val);
- }
+ conf->hooks_env = svn_dirent_internal_style(arg1, cmd->pool);
return NULL;
}
@@ -689,6 +697,16 @@ dav_svn__get_master_uri(request_rec *r)
}
+svn_version_t *
+dav_svn__get_master_version(request_rec *r)
+{
+ dir_conf_t *conf;
+
+ conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+ return conf->master_uri ? conf->master_version : NULL;
+}
+
+
const char *
dav_svn__get_xslt_uri(request_rec *r)
{
@@ -786,12 +804,39 @@ dav_svn__get_bulk_updates_flag(request_r
svn_boolean_t
-dav_svn__get_v2_protocol_flag(request_rec *r)
+dav_svn__check_httpv2_support(request_rec *r)
{
dir_conf_t *conf;
+ svn_boolean_t available;
conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
- return conf->v2_protocol == CONF_FLAG_ON;
+ available = conf->v2_protocol == CONF_FLAG_ON;
+
+ /* If our configuration says that HTTPv2 is available, but we are
+ proxying requests to a master Subversion server which lacks
+ support for HTTPv2, we dumb ourselves down. */
+ if (available)
+ {
+ svn_version_t *version = dav_svn__get_master_version(r);
+ if (version && (! svn_version__at_least(version, 1, 7, 0)))
+ available = FALSE;
+ }
+ return available;
+}
+
+
+svn_boolean_t
+dav_svn__check_ephemeral_txnprops_support(request_rec *r)
+{
+ svn_version_t *version = dav_svn__get_master_version(r);
+
+ /* We know this server supports ephemeral txnprops. But if we're
+ proxying requests to a master server, we need to see if it
+ supports them, too. */
+ if (version && (! svn_version__at_least(version, 1, 8, 0)))
+ return FALSE;
+
+ return TRUE;
}
@@ -873,12 +918,24 @@ dav_svn__get_revprop_cache_flag(request_
int
-dav_svn__get_compression_level(void)
+dav_svn__get_compression_level(request_rec *r)
{
- return svn__compression_level;
+ server_conf_t *conf;
+
+ conf = ap_get_module_config(r->server->module_config,
+ &dav_svn_module);
+
+ if (conf->compression_level < 0)
+ {
+ return SVN_DELTA_COMPRESSION_LEVEL_DEFAULT;
+ }
+ else
+ {
+ return conf->compression_level;
+ }
}
-apr_hash_t *
+const char *
dav_svn__get_hooks_env(request_rec *r)
{
dir_conf_t *conf;
@@ -1077,6 +1134,11 @@ static const command_rec cmds[] =
"specifies a URI to access a master Subversion repository"),
/* per directory/location */
+ AP_INIT_TAKE1("SVNMasterVersion", SVNMasterVersion_cmd, NULL, ACCESS_CONF,
+ "specifies the Subversion release version of a master "
+ "Subversion server "),
+
+ /* per directory/location */
AP_INIT_TAKE1("SVNActivitiesDB", SVNActivitiesDB_cmd, NULL, ACCESS_CONF,
"specifies the location in the filesystem in which the "
"activities database(s) should be stored"),
@@ -1136,10 +1198,12 @@ static const command_rec cmds[] =
"use UTF-8 as native character encoding (default is ASCII)."),
/* per directory/location */
- AP_INIT_ITERATE("SVNHooksEnv", SVNHooksEnv_cmd, NULL,
- ACCESS_CONF|RSRC_CONF,
- "Set the environment of hook scripts via any number of "
- "VAR=VAL arguments (the default hook environment is empty)."),
+ AP_INIT_TAKE1("SVNHooksEnv", SVNHooksEnv_cmd, NULL,
+ ACCESS_CONF|RSRC_CONF,
+ "Sets the path to the configuration file for the environment "
+ "of hook scripts. If not absolute, the path is relative to "
+ "the repository's conf directory (by default the hooks-env "
+ "file in the repository is used)."),
{ NULL }
};
Modified: subversion/branches/compressed-pristines/subversion/mod_dav_svn/posts/create_txn.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/mod_dav_svn/posts/create_txn.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/mod_dav_svn/posts/create_txn.c (original)
+++ subversion/branches/compressed-pristines/subversion/mod_dav_svn/posts/create_txn.c Sat Nov 24 20:29:11 2012
@@ -42,13 +42,64 @@ dav_svn__post_create_txn(const dav_resou
request_rec *r = resource->info->r;
/* Create a Subversion repository transaction based on HEAD. */
- if ((derr = dav_svn__create_txn(resource->info->repos, &txn_name,
+ if ((derr = dav_svn__create_txn(resource->info->repos, &txn_name, NULL,
resource->pool)))
return derr;
/* Build a "201 Created" response with header that tells the
client our new transaction's name. */
- vtxn_name = apr_table_get(r->headers_in, SVN_DAV_VTXN_NAME_HEADER);
+ vtxn_name = apr_table_get(r->headers_in, SVN_DAV_VTXN_NAME_HEADER);
+ if (vtxn_name && vtxn_name[0])
+ {
+ /* If the client supplied a vtxn name then store a mapping from
+ the client name to the FS transaction name in the activity
+ database. */
+ if ((derr = dav_svn__store_activity(resource->info->repos,
+ vtxn_name, txn_name)))
+ return derr;
+ apr_table_set(r->headers_out, SVN_DAV_VTXN_NAME_HEADER, vtxn_name);
+ }
+ else
+ apr_table_set(r->headers_out, SVN_DAV_TXN_NAME_HEADER, txn_name);
+
+ r->status = HTTP_CREATED;
+
+ return NULL;
+}
+
+
+/* Respond to a "create-txn-with-props" POST request.
+ *
+ * Syntax: ( create-txn-with-props (PROPNAME PROPVAL [PROPNAME PROPVAL ...])
+ */
+dav_error *
+dav_svn__post_create_txn_with_props(const dav_resource *resource,
+ svn_skel_t *request_skel,
+ ap_filter_t *output)
+{
+ const char *txn_name;
+ const char *vtxn_name;
+ dav_error *derr;
+ svn_error_t *err;
+ request_rec *r = resource->info->r;
+ apr_hash_t *revprops;
+ svn_skel_t *proplist_skel = request_skel->children->next;
+
+ if ((err = svn_skel__parse_proplist(&revprops, proplist_skel,
+ resource->pool)))
+ {
+ return dav_svn__convert_err(err, HTTP_BAD_REQUEST,
+ "Malformatted request skel", resource->pool);
+ }
+
+ /* Create a Subversion repository transaction based on HEAD. */
+ if ((derr = dav_svn__create_txn(resource->info->repos, &txn_name,
+ revprops, resource->pool)))
+ return derr;
+
+ /* Build a "201 Created" response with header that tells the
+ client our new transaction's name. */
+ vtxn_name = apr_table_get(r->headers_in, SVN_DAV_VTXN_NAME_HEADER);
if (vtxn_name && vtxn_name[0])
{
/* If the client supplied a vtxn name then store a mapping from