You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by vm...@apache.org on 2012/12/27 05:03:55 UTC
svn commit: r1426116 [10/16] - in /subversion/branches/javahl-ra: ./ build/
build/ac-macros/ build/generator/ build/win32/
contrib/server-side/svncutter/ notes/ subversion/bindings/cxxhl/
subversion/bindings/swig/ subversion/bindings/swig/perl/native/ ...
Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db.h?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db.h Thu Dec 27 04:03:49 2012
@@ -74,7 +74,7 @@ extern "C" {
The pool that DB is allocated within (the "state" pool) is only used
for a few, limited allocations to track each of the working copy roots
that the DB is asked to operate upon. The memory usage on this pool
- os O(# wcroots), which should normally be one or a few. Custom clients
+ is O(# wcroots), which should normally be one or a few. Custom clients
which hold open structures over a significant period of time should
pay particular attention to the number of roots touched, and the
resulting impact on memory consumption (which should still be minimal).
@@ -134,7 +134,8 @@ typedef enum svn_wc__db_status_t {
svn_wc__db_status_normal,
/* The node has been added (potentially obscuring a delete or move of
- the BASE node; see HAVE_BASE param). The text will be marked as
+ the BASE node; see HAVE_BASE param [### What param? This is an enum
+ not a function.] ). The text will be marked as
modified, and if properties exist, they will be marked as modified.
In many cases svn_wc__db_status_added means any of added, moved-here
@@ -212,7 +213,7 @@ typedef struct svn_wc__db_lock_t {
/*
- @defgroup svn_wc__db_admin General administractive functions
+ @defgroup svn_wc__db_admin General administrative functions
@{
*/
@@ -511,6 +512,7 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
svn_boolean_t delete_working,
svn_boolean_t update_actual_props,
apr_hash_t *new_actual_props,
+ apr_array_header_t *new_iprops,
svn_boolean_t keep_recorded_info,
svn_boolean_t insert_base_deleted,
const svn_skel_t *conflict,
@@ -593,6 +595,7 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
svn_boolean_t delete_working,
svn_boolean_t update_actual_props,
apr_hash_t *new_actual_props,
+ apr_array_header_t *new_iprops,
svn_boolean_t keep_recorded_info,
svn_boolean_t insert_base_deleted,
const svn_skel_t *conflict,
@@ -726,6 +729,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
LOCK NULL
HAD_PROPS FALSE
+ PROPS NULL
UPDATE_ROOT FALSE
@@ -741,6 +745,11 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
If TARGET is requested, and the node is NOT a symlink, then it will
be set to NULL.
+ *PROPS maps "const char *" names to "const svn_string_t *" values. If
+ the base node is capable of having properties but has none, set
+ *PROPS to an empty hash. If its status is such that it cannot have
+ properties, set *PROPS to NULL.
+
If UPDATE_ROOT is requested, set it to TRUE if the node should only
be updated when it is the root of an update (e.g. file externals).
@@ -762,6 +771,7 @@ svn_wc__db_base_get_info(svn_wc__db_stat
const char **target,
svn_wc__db_lock_t **lock,
svn_boolean_t *had_props,
+ apr_hash_t **props,
svn_boolean_t *update_root,
svn_wc__db_t *db,
const char *local_abspath,
@@ -797,7 +807,8 @@ svn_wc__db_base_get_children_info(apr_ha
*PROPS maps "const char *" names to "const svn_string_t *" values.
If the node has no properties, set *PROPS to an empty hash.
*PROPS will never be set to NULL.
- If the node is not present in the BASE tree, return an error.
+ If the node is not present in the BASE tree (with presence 'normal'
+ or 'incomplete'), return an error.
Allocate *PROPS and its keys and values in RESULT_POOL.
*/
svn_error_t *
@@ -1147,7 +1158,7 @@ svn_wc__db_external_remove(svn_wc__db_t
When KIND is requested then the value will be set to the kind of external.
- If DEFININING_ABSPATH is requested, then the value will be set to the
+ If DEFINING_ABSPATH is requested, then the value will be set to the
absolute path of the directory which originally defined the external.
(The path with the svn:externals property)
@@ -1281,7 +1292,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
* of SRC_ABSPATH (so SRC_ABSPATH must be an op_root) to dst_abspaths
* parents layer.
*
- * This operation is recursive. It copies all the descandants at the lower
+ * This operation is recursive. It copies all the descendants at the lower
* layer and adds base-deleted nodes on dst_abspath layer to mark these nodes
* properly deleted.
*
@@ -1406,8 +1417,8 @@ svn_wc__db_op_add_symlink(svn_wc__db_t *
If PROPS is NULL, set the properties to be the same as the pristine
properties.
- CONFLICT is used to register a conflict on this node at the same time
- the properties are changed.
+ If CONFLICT is not NULL, it is used to register a conflict on this
+ node at the same time the properties are changed.
WORK_ITEMS are inserted into the work queue, as additional things that
need to be completed before the working copy is stable.
@@ -1434,42 +1445,6 @@ svn_wc__db_op_set_props(svn_wc__db_t *db
const svn_skel_t *work_items,
apr_pool_t *scratch_pool);
-/* See props.h */
-#ifdef SVN__SUPPORT_BASE_MERGE
-/* ### Set the properties of the node LOCAL_ABSPATH in the BASE tree to PROPS.
- ###
- ### This function should not exist because properties should be stored
- ### onto the BASE node at construction time, in a single atomic operation.
- ###
- ### PROPS maps "const char *" names to "const svn_string_t *" values.
- ### To specify no properties, PROPS must be an empty hash, not NULL.
- ### If the node is not present, SVN_ERR_WC_PATH_NOT_FOUND is returned.
-*/
-svn_error_t *
-svn_wc__db_temp_base_set_props(svn_wc__db_t *db,
- const char *local_abspath,
- const apr_hash_t *props,
- apr_pool_t *scratch_pool);
-
-
-/* ### Set the properties of the node LOCAL_ABSPATH in the WORKING tree
- ### to PROPS.
- ###
- ### This function should not exist because properties should be stored
- ### onto the WORKING node at construction time, in a single atomic
- ### operation.
- ###
- ### PROPS maps "const char *" names to "const svn_string_t *" values.
- ### To specify no properties, PROPS must be an empty hash, not NULL.
- ### If the node is not present, SVN_ERR_WC_PATH_NOT_FOUND is returned.
-*/
-svn_error_t *
-svn_wc__db_temp_working_set_props(svn_wc__db_t *db,
- const char *local_abspath,
- const apr_hash_t *props,
- apr_pool_t *scratch_pool);
-#endif
-
/* Mark LOCAL_ABSPATH, and all children, for deletion.
*
* This function removes the file externals (and if DELETE_DIR_EXTERNALS is
@@ -1720,7 +1695,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t
LOCK NULL
RECORDED_SIZE SVN_INVALID_FILESIZE
- RECORDED_MOD_TIME 0
+ RECORDED_TIME 0
CHANGELIST NULL
CONFLICTED FALSE
@@ -1804,7 +1779,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t
If HAD_PROPS is requested and the node has pristine props, the value will
be set to TRUE.
- If PROP_MODS is requested and the node has property modification the value
+ If PROPS_MOD is requested and the node has property modification the value
will be set to TRUE.
### add information about the need to scan upwards to get a complete
@@ -1815,7 +1790,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t
### the TEXT_MOD may become an enumerated value at some point to
### indicate different states of knowledge about text modifications.
### for example, an "svn edit" command in the future might set a
- ### flag indicating adminstratively-defined modification. and/or we
+ ### flag indicating administratively-defined modification. and/or we
### might have a status indicating that we saw it was modified while
### performing a filesystem traversal.
@@ -1872,7 +1847,7 @@ svn_wc__db_read_info(svn_wc__db_status_t
/* Recorded for files present in the working copy */
svn_filesize_t *recorded_size,
- apr_time_t *recorded_mod_time,
+ apr_time_t *recorded_time,
/* From ACTUAL */
const char **changelist,
@@ -1908,7 +1883,7 @@ struct svn_wc__db_info_t {
svn_depth_t depth;
svn_filesize_t recorded_size;
- apr_time_t recorded_mod_time;
+ apr_time_t recorded_time;
const char *changelist;
svn_boolean_t conflicted;
@@ -1972,6 +1947,11 @@ struct svn_wc__db_walker_info_t {
calling svn_wc__db_read_info().
(All other information (like original_*) can be obtained via other apis).
+
+ *PROPS maps "const char *" names to "const svn_string_t *" values. If
+ the pristine node is capable of having properties but has none, set
+ *PROPS to an empty hash. If its status is such that it cannot have
+ properties, set *PROPS to NULL.
*/
svn_error_t *
svn_wc__db_read_pristine_info(svn_wc__db_status_t *status,
@@ -1983,6 +1963,7 @@ svn_wc__db_read_pristine_info(svn_wc__db
const svn_checksum_t **checksum, /* files only */
const char **target, /* symlinks only */
svn_boolean_t *had_props,
+ apr_hash_t **props,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -2010,7 +1991,7 @@ svn_wc__db_read_node_install_info(const
apr_pool_t *scratch_pool);
/* Return in *NODES a hash mapping name->struct svn_wc__db_walker_info_t for
- the children of DIR_ABSPATH. "name" is the child's name relatve to
+ the children of DIR_ABSPATH. "name" is the child's name relative to
DIR_ABSPATH, not an absolute path. */
svn_error_t *
svn_wc__db_read_children_walker_info(apr_hash_t **nodes,
@@ -2054,11 +2035,8 @@ svn_wc__db_read_props(apr_hash_t **props
* a hash table mapping <tt>char *</tt> names onto svn_string_t *
* values for any properties of child nodes of LOCAL_ABSPATH (up to DEPTH).
*
- * If BASE_PROPS is FALSE, read the properties from the WORKING layer (highest
- * op_depth).
- *
- * If BASE_PROPS is FALSE and, PRISTINE is TRUE, the local modifications will
- * be suppressed. If PRISTINE is FALSE, local modifications will be visible.
+ * If PRISTINE is FALSE, read the properties from the WORKING layer (highest
+ * op_depth); if PRISTINE is FALSE, local modifications will be visible.
*/
svn_error_t *
svn_wc__db_read_props_streamily(svn_wc__db_t *db,
@@ -2091,6 +2069,26 @@ svn_wc__db_read_pristine_props(apr_hash_
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+
+/**
+ * Set @a *inherited_props to a depth-first ordered array of
+ * #svn_prop_inherited_item_t * structures representing the properties
+ * inherited by @a local_abspath from the ACTUAL tree above
+ * @a local_abspath (looking through to the WORKING or BASE tree as
+ * required), up to and including the root of the working copy and
+ * any cached inherited properties inherited by the root.
+ *
+ * Allocate @a *inherited_props in @a result_pool. Use @a scratch_pool
+ * for temporary allocations.
+ */
+svn_error_t *
+svn_wc__db_read_inherited_props(apr_array_header_t **iprops,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *propname,
+ 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
@@ -2113,9 +2111,11 @@ svn_wc__db_read_cached_iprops(apr_array_
/* 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.
+ paths to the repos_relpath of the path 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,
@@ -2146,7 +2146,7 @@ svn_wc__db_prop_retrieve_recursive(apr_h
Return every path that refers to a child of the working node at
LOCAL_ABSPATH. Do not include a path just because it was a child of a
deleted directory that existed at LOCAL_ABSPATH if that directory is now
- sheduled to be replaced by the working node at LOCAL_ABSPATH.
+ scheduled to be replaced by the working node at LOCAL_ABSPATH.
Allocate *CHILDREN in RESULT_POOL and do temporary allocations in
SCRATCH_POOL.
@@ -2277,16 +2277,36 @@ svn_wc__db_node_check_replace(svn_boolea
### changelist usage -- we may already assume the list fits in memory.
*/
-/* Checks if LOCAL_ABSPATH has a parent directory that knows about its
- * existance. Set *IS_ROOT to FALSE if a parent is found, and to TRUE
- * if there is no such parent.
+/* The DB-private version of svn_wc__is_wcroot(), which see.
*/
svn_error_t *
-svn_wc__db_is_wcroot(svn_boolean_t *is_root,
+svn_wc__db_is_wcroot(svn_boolean_t *is_wcroot,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool);
+/* Check whether a node is a working copy root and/or switched.
+
+ If LOCAL_ABSPATH is the root of a working copy, set *IS_WC_ROOT to TRUE,
+ otherwise to FALSE.
+
+ If LOCAL_ABSPATH is switched against its parent in the same working copy
+ set *IS_SWITCHED to TRUE, otherwise to FALSE.
+
+ If KIND is not null, set *KIND to the node type of LOCAL_ABSPATH.
+
+ Any of the output arguments can be null to specify that the result is not
+ interesting to the caller.
+
+ Use SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+svn_wc__db_is_switched(svn_boolean_t *is_wcroot,
+ svn_boolean_t *is_switched,
+ svn_kind_t *kind,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool);
/* @} */
@@ -2333,7 +2353,7 @@ svn_wc__db_global_relocate(svn_wc__db_t
CHANGED_REVISION is the new 'last changed' revision. If the node is
modified its value is equivalent to NEW_REVISION, but in case of a
- decendant of a copy/move it can be an older revision.
+ descendant of a copy/move it can be an older revision.
CHANGED_DATE is the (server-side) date of CHANGED_REVISION. It may be 0 if
the revprop is missing on the revision.
@@ -2456,23 +2476,23 @@ svn_wc__db_op_bump_revisions_post_update
apr_pool_t *scratch_pool);
-/* Record the TRANSLATED_SIZE and LAST_MOD_TIME for a versioned node.
+/* Record the RECORDED_SIZE and RECORDED_TIME for a versioned node.
This function will record the information within the WORKING node,
if present, or within the BASE tree. If neither node is present, then
SVN_ERR_WC_PATH_NOT_FOUND will be returned.
- TRANSLATED_SIZE may be SVN_INVALID_FILESIZE, which will be recorded
+ RECORDED_SIZE may be SVN_INVALID_FILESIZE, which will be recorded
as such, implying "unknown size".
- LAST_MOD_TIME may be 0, which will be recorded as such, implying
+ RECORDED_TIME may be 0, which will be recorded as such, implying
"unknown last mod time".
*/
svn_error_t *
svn_wc__db_global_record_fileinfo(svn_wc__db_t *db,
const char *local_abspath,
- svn_filesize_t translated_size,
- apr_time_t last_mod_time,
+ svn_filesize_t recorded_size,
+ apr_time_t recorded_time,
apr_pool_t *scratch_pool);
@@ -3076,7 +3096,7 @@ svn_wc__db_get_not_present_descendants(c
* Only nodes with op_depth zero and presence 'normal' or 'incomplete'
* are considered, so that added, deleted or excluded nodes do not affect
* the result. If COMMITTED is TRUE, set *MIN_REVISION and *MAX_REVISION
- * to the lowest and highest comitted (i.e. "last changed") revision numbers,
+ * to the lowest and highest committed (i.e. "last changed") revision numbers,
* respectively.
*
* Indicate in *IS_SPARSE_CHECKOUT whether any of the nodes within
@@ -3111,7 +3131,7 @@ svn_wc__db_revision_status(svn_revnum_t
* Only nodes with op_depth zero and presence 'normal' or 'incomplete'
* are considered, so that added, deleted or excluded nodes do not affect
* the result. If COMMITTED is TRUE, set *MIN_REVISION and *MAX_REVISION
- * to the lowest and highest comitted (i.e. "last changed") revision numbers,
+ * to the lowest and highest committed (i.e. "last changed") revision numbers,
* respectively. Use SCRATCH_POOL for temporary allocations.
*
* Either of MIN_REVISION and MAX_REVISION may be passed as NULL if
@@ -3207,8 +3227,8 @@ svn_wc__db_follow_moved_to(apr_array_hea
* 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,
+ const char *victim_abspath,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
@@ -3216,6 +3236,13 @@ svn_wc__db_update_moved_away_conflict_vi
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Recover space from the database file for LOCAL_ABSPATH by running
+ * the "vacuum" command. */
+svn_error_t *
+svn_wc__db_vacuum(svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool);
+
/* @} */
Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_private.h?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_private.h Thu Dec 27 04:03:49 2012
@@ -96,7 +96,7 @@ typedef struct svn_wc__db_wcroot_t {
Typically just one or two locks maximum. */
apr_array_header_t *owned_locks;
- /* Map a working copy diretory to a cached adm_access baton.
+ /* Map a working copy directory to a cached adm_access baton.
const char *local_abspath -> svn_wc_adm_access_t *adm_access */
apr_hash_t *access_cache;
@@ -254,6 +254,7 @@ svn_wc__db_base_get_info_internal(svn_wc
const char **target,
svn_wc__db_lock_t **lock,
svn_boolean_t *had_props,
+ apr_hash_t **props,
svn_boolean_t *update_root,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
@@ -262,7 +263,18 @@ svn_wc__db_base_get_info_internal(svn_wc
/* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH
* instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get
- * information about, and outputting REPOS_ID instead of URL+UUID. */
+ * information about, and outputting REPOS_ID instead of URL+UUID, and
+ * without the LOCK or UPDATE_ROOT outputs.
+ *
+ * OR
+ *
+ * Similar to svn_wc__db_base_get_info_internal(), but taking an explicit
+ * op-depth OP_DEPTH of the node to get information about, and without the
+ * LOCK or UPDATE_ROOT outputs.
+ *
+ * ### [JAF] TODO: Harmonize svn_wc__db_base_get_info[_internal] with
+ * svn_wc__db_depth_get_info -- common API, common implementation.
+ */
svn_error_t *
svn_wc__db_depth_get_info(svn_wc__db_status_t *status,
svn_kind_t *kind,
@@ -276,6 +288,7 @@ svn_wc__db_depth_get_info(svn_wc__db_sta
const svn_checksum_t **checksum,
const char **target,
svn_boolean_t *had_props,
+ apr_hash_t **props,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
int op_depth,
@@ -291,6 +304,14 @@ svn_wc__db_read_conflict_internal(svn_sk
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Like svn_wc__db_op_mark_conflict(), but with WCROOT+LOCAL_RELPATH instead of
+ DB+LOCAL_ABSPATH. */
+svn_error_t *
+svn_wc__db_mark_conflict_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ const svn_skel_t *conflict_skel,
+ apr_pool_t *scratch_pool);
+
/* Transaction handling */
@@ -312,4 +333,28 @@ svn_wc__db_with_txn(svn_wc__db_wcroot_t
apr_pool_t *scratch_pool);
+/* Return CHILDREN mapping const char * names to svn_kind_t * for the
+ children of LOCAL_RELPATH at OP_DEPTH. */
+svn_error_t *
+svn_wc__db_get_children_op_depth(apr_hash_t **children,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ int op_depth,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+
+svn_error_t *
+svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_kind_t kind,
+ int op_depth,
+ apr_pool_t *scratch_pool);
+
+svn_error_t *
+svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ int op_depth,
+ apr_pool_t *scratch_pool);
+
#endif /* WC_DB_PRIVATE_H */
Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_update_move.c?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_update_move.c Thu Dec 27 04:03:49 2012
@@ -38,7 +38,9 @@
#include "svn_dirent_uri.h"
#include "svn_editor.h"
#include "svn_error.h"
+#include "svn_hash.h"
#include "svn_wc.h"
+#include "svn_props.h"
#include "svn_pools.h"
#include "private/svn_skel.h"
@@ -46,6 +48,7 @@
#include "private/svn_wc_private.h"
#include "wc.h"
+#include "props.h"
#include "wc_db_private.h"
#include "wc-queries.h"
#include "conflicts.h"
@@ -53,14 +56,18 @@
/*
* Receiver code.
+ *
+ * The receiver is an editor that, when driven with a certain change, will
+ * merge the edits into the 'actual' layer of a moved subtree.
*/
struct tc_editor_baton {
- const char *move_root_src_relpath;
- const char *move_root_dst_relpath;
+ svn_skel_t **work_items;
svn_wc__db_t *db;
svn_wc__db_wcroot_t *wcroot;
- svn_skel_t **work_items;
+ const char *move_root_src_relpath;
+ const char *move_root_dst_relpath;
+ int src_op_depth;
svn_wc_conflict_version_t *old_version;
svn_wc_conflict_version_t *new_version;
svn_wc_notify_func2_t notify_func;
@@ -76,7 +83,15 @@ tc_editor_add_directory(void *baton,
svn_revnum_t replaces_rev,
apr_pool_t *scratch_pool)
{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+ struct tc_editor_baton *b = baton;
+ int op_depth = relpath_depth(b->move_root_dst_relpath);
+
+ SVN_ERR(svn_wc__db_extend_parent_delete(b->wcroot, relpath, svn_kind_dir,
+ op_depth, scratch_pool));
+
+ /* ### TODO check for, and flag, tree conflict */
+
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -88,7 +103,15 @@ tc_editor_add_file(void *baton,
svn_revnum_t replaces_rev,
apr_pool_t *scratch_pool)
{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+ struct tc_editor_baton *b = baton;
+ int op_depth = relpath_depth(b->move_root_dst_relpath);
+
+ SVN_ERR(svn_wc__db_extend_parent_delete(b->wcroot, relpath, svn_kind_file,
+ op_depth, scratch_pool));
+
+ /* ### TODO check for, and flag, tree conflict */
+
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -112,72 +135,261 @@ tc_editor_add_absent(void *baton,
return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
}
+/* All the info we need about one version of a working node. */
+typedef struct working_node_version_t
+{
+ svn_wc_conflict_version_t *location_and_kind;
+ apr_hash_t *props;
+ const svn_checksum_t *checksum; /* for files only */
+} working_node_version_t;
+
+static svn_error_t *
+create_conflict_markers(svn_skel_t **work_items,
+ const char *local_abspath,
+ svn_wc__db_t *db,
+ const char *repos_relpath,
+ svn_skel_t *conflict_skel,
+ const working_node_version_t *old_version,
+ const working_node_version_t *new_version,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_skel_t *work_item;
+ svn_wc_conflict_version_t *original_version;
+
+ original_version = svn_wc_conflict_version_dup(
+ old_version->location_and_kind, scratch_pool);
+ original_version->path_in_repos = 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));
+ /* According to this func's doc string, it is "Currently only used for
+ * property conflicts as text conflict markers are just in-wc files." */
+ SVN_ERR(svn_wc__conflict_create_markers(&work_item, db,
+ local_abspath,
+ conflict_skel,
+ scratch_pool,
+ scratch_pool));
+ *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+
+ return SVN_NO_ERROR;
+}
+
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)
+update_working_props(svn_wc_notify_state_t *prop_state,
+ svn_skel_t **conflict_skel,
+ apr_array_header_t **propchanges,
+ apr_hash_t **actual_props,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ const struct working_node_version_t *old_version,
+ const struct working_node_version_t *new_version,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+ apr_hash_t *new_actual_props;
+
+ /*
+ * Run a 3-way prop merge to update the props, using the pre-update
+ * props as the merge base, the post-update props as the
+ * merge-left version, and the current props of the
+ * moved-here working file as the merge-right version.
+ */
+ SVN_ERR(svn_wc__db_read_props(actual_props,
+ db, local_abspath,
+ result_pool, scratch_pool));
+ SVN_ERR(svn_prop_diffs(propchanges, new_version->props, old_version->props,
+ result_pool));
+ SVN_ERR(svn_wc__merge_props(conflict_skel, prop_state,
+ NULL, &new_actual_props,
+ db, local_abspath,
+ old_version->props, old_version->props,
+ *actual_props, *propchanges,
+ result_pool, scratch_pool));
+ /* Install the new actual props. Don't set the conflict_skel yet, because
+ we might need to add a text conflict to it as well. */
+ SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
+ new_actual_props,
+ svn_wc__has_magic_property(*propchanges),
+ NULL/*conflict_skel*/, NULL/*work_items*/,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
}
-/* Check whether the node at LOCAL_RELPATH in the working copy at WCROOT
- * is shadowed by some node at a higher op depth than EXPECTED_OP_DEPTH. */
+/* If LOCAL_ABSPATH is shadowed then raise a tree-conflict on the root
+ of the obstruction if such a tree-conflict does not already exist. */
static svn_error_t *
-check_shadowed_node(svn_boolean_t *is_shadowed,
- int expected_op_depth,
+check_tree_conflict(svn_boolean_t *is_conflicted,
+ struct tc_editor_baton *b,
const char *local_relpath,
- svn_wc__db_wcroot_t *wcroot)
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ int dst_op_depth = relpath_depth(b->move_root_dst_relpath);
+ int op_depth;
+ const char *conflict_root_relpath = local_relpath;
+ svn_skel_t *conflict;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_SELECT_LOWEST_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, local_relpath,
+ dst_op_depth));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ op_depth = svn_sqlite__column_int(stmt, 0);
+ SVN_ERR(svn_sqlite__reset(stmt));
- while (have_row)
+ if (!have_row)
{
- int op_depth = svn_sqlite__column_int(stmt, 0);
+ *is_conflicted = FALSE;
+ return SVN_NO_ERROR;
+ }
+
+ *is_conflicted = TRUE;
+
+ while (relpath_depth(conflict_root_relpath) > op_depth)
+ conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
+ scratch_pool);
+
+ SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, b->wcroot,
+ conflict_root_relpath,
+ scratch_pool, scratch_pool));
+
+ if (conflict)
+ /* ### TODO: check this is the right sort of tree-conflict? */
+ return SVN_NO_ERROR;
+
+ conflict = svn_wc__conflict_skel_create(scratch_pool);
+ SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+ conflict, NULL,
+ svn_dirent_join(b->wcroot->abspath, conflict_root_relpath,
+ scratch_pool),
+ svn_wc_conflict_reason_moved_away,
+ svn_wc_conflict_action_edit,
+ scratch_pool,
+ scratch_pool));
+
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict, b->old_version,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, conflict_root_relpath,
+ conflict, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
- if (op_depth > expected_op_depth)
- {
- *is_shadowed = TRUE;
- SVN_ERR(svn_sqlite__reset(stmt));
- return SVN_NO_ERROR;
+static svn_error_t *
+tc_editor_alter_directory(void *baton,
+ const char *dst_relpath,
+ svn_revnum_t expected_move_dst_revision,
+ const apr_array_header_t *children,
+ apr_hash_t *new_props,
+ apr_pool_t *scratch_pool)
+{
+ struct tc_editor_baton *b = baton;
+ const char *move_dst_repos_relpath;
+ svn_revnum_t move_dst_revision;
+ svn_kind_t move_dst_kind;
+ working_node_version_t old_version, new_version;
+ svn_wc__db_status_t status;
+ svn_boolean_t is_conflicted;
+
+ SVN_ERR_ASSERT(expected_move_dst_revision == b->old_version->peg_rev);
+
+ SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath, scratch_pool));
+ if (is_conflicted)
+ return SVN_NO_ERROR;
+
+ /* Get kind, revision, and checksum of the moved-here node. */
+ SVN_ERR(svn_wc__db_depth_get_info(&status, &move_dst_kind, &move_dst_revision,
+ &move_dst_repos_relpath, NULL, NULL, NULL,
+ NULL, NULL, &old_version.checksum, NULL,
+ NULL, &old_version.props,
+ b->wcroot, dst_relpath,
+ relpath_depth(b->move_root_dst_relpath),
+ scratch_pool, scratch_pool));
+ SVN_ERR_ASSERT(move_dst_revision == expected_move_dst_revision);
+ SVN_ERR_ASSERT(move_dst_kind == svn_kind_dir);
+
+ old_version.location_and_kind = b->old_version;
+ new_version.location_and_kind = b->new_version;
+
+ new_version.checksum = NULL; /* not a file */
+ new_version.props = new_props ? new_props : old_version.props;
+
+ if (new_props)
+ {
+ const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
+ dst_relpath,
+ scratch_pool);
+ svn_wc_notify_state_t prop_state;
+ svn_skel_t *conflict_skel = NULL;
+ apr_hash_t *actual_props;
+ apr_array_header_t *propchanges;
+
+ SVN_ERR(update_working_props(&prop_state, &conflict_skel,
+ &propchanges, &actual_props,
+ b->db, dst_abspath,
+ &old_version, &new_version,
+ b->result_pool, scratch_pool));
+
+ if (conflict_skel)
+ {
+ SVN_ERR(create_conflict_markers(b->work_items, dst_abspath,
+ b->db, move_dst_repos_relpath,
+ conflict_skel,
+ &old_version, &new_version,
+ b->result_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, dst_relpath,
+ conflict_skel,
+ scratch_pool));
}
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
+ if (b->notify_func)
+ {
+ svn_wc_notify_t *notify;
- *is_shadowed = FALSE;
- SVN_ERR(svn_sqlite__reset(stmt));
+ notify = svn_wc_create_notify(dst_abspath,
+ svn_wc_notify_update_update,
+ scratch_pool);
+ notify->kind = svn_node_dir;
+ notify->content_state = svn_wc_notify_state_inapplicable;
+ notify->prop_state = prop_state;
+ 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;
}
-/* Update text and prop contents of the working file at DST_RELPATH
- * in the working copy at WCROOT, from OLD_VERSION to NEW_VERSION,
- * based on pristine contents identified by MOVE_SRC_CHECKSUM and
- * MOVE_DST_CHECKSUM. MOVE_DST_REPOS_RELPATH is the repository path
- * the node at DST_RELPATH would be committed to.
- * Use working copy database DB.
+
+/* Merge the difference between OLD_VERSION and NEW_VERSION into
+ * the working file at LOCAL_RELPATH.
+ *
+ * The term 'old' refers to the pre-update state, which is the state of
+ * (some layer of) LOCAL_RELPATH while this function runs; and 'new'
+ * refers to the post-update state, as found at the (base layer of) the
+ * move source path while this function runs.
+ *
+ * LOCAL_RELPATH is a file in the working copy at WCROOT in DB, and
+ * REPOS_RELPATH is the repository path it would be committed to.
+ *
* Use NOTIFY_FUNC and NOTIFY_BATON for notifications.
- * Add any required work items to *WORK_ITEMS, allocated in RESULT_POOL.
+ * Set *WORK_ITEMS to any required work items, allocated in RESULT_POOL.
* Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
update_working_file(svn_skel_t **work_items,
- const char *dst_relpath,
- const char *move_dst_repos_relpath,
- const svn_checksum_t *move_src_checksum,
- const svn_checksum_t *move_dst_checksum,
- svn_wc_conflict_version_t *old_version,
- svn_wc_conflict_version_t *new_version,
+ const char *local_relpath,
+ const char *repos_relpath,
+ const working_node_version_t *old_version,
+ const working_node_version_t *new_version,
svn_wc__db_wcroot_t *wcroot,
svn_wc__db_t *db,
svn_wc_notify_func2_t notify_func,
@@ -185,15 +397,31 @@ update_working_file(svn_skel_t **work_it
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- const char *moved_to_abspath = svn_dirent_join(wcroot->abspath,
- dst_relpath,
- scratch_pool);
- const char *pre_update_pristine_abspath;
- const char *post_update_pristine_abspath;
- svn_skel_t *conflict_skel;
+ const char *local_abspath = svn_dirent_join(wcroot->abspath,
+ local_relpath,
+ scratch_pool);
+ const char *old_pristine_abspath;
+ const char *new_pristine_abspath;
+ svn_skel_t *conflict_skel = NULL;
+ apr_hash_t *actual_props;
+ apr_array_header_t *propchanges;
enum svn_wc_merge_outcome_t merge_outcome;
- svn_wc_notify_state_t content_state;
- svn_wc_notify_t *notify;
+ svn_wc_notify_state_t prop_state, content_state;
+
+ SVN_ERR(update_working_props(&prop_state, &conflict_skel, &propchanges,
+ &actual_props, db, local_abspath,
+ old_version, new_version,
+ result_pool, scratch_pool));
+
+ /* If there are any conflicts to be stored, convert them into work items
+ * too. */
+ if (conflict_skel)
+ {
+ SVN_ERR(create_conflict_markers(work_items, local_abspath, db,
+ repos_relpath, conflict_skel,
+ old_version, new_version,
+ result_pool, scratch_pool));
+ }
/*
* Run a 3-way merge to update the file, using the pre-update
@@ -201,51 +429,44 @@ update_working_file(svn_skel_t **work_it
* 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,
+ SVN_ERR(svn_wc__db_pristine_get_path(&old_pristine_abspath,
db, wcroot->abspath,
- move_dst_checksum,
+ old_version->checksum,
scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__db_pristine_get_path(&post_update_pristine_abspath,
+ SVN_ERR(svn_wc__db_pristine_get_path(&new_pristine_abspath,
db, wcroot->abspath,
- move_src_checksum,
+ new_version->checksum,
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__internal_merge(work_items, &conflict_skel,
&merge_outcome, db,
- pre_update_pristine_abspath,
- post_update_pristine_abspath,
- moved_to_abspath,
- moved_to_abspath,
+ old_pristine_abspath,
+ new_pristine_abspath,
+ local_abspath,
+ local_abspath,
NULL, NULL, NULL, /* diff labels */
- NULL, /* actual props */
+ actual_props,
FALSE, /* dry-run */
NULL, /* diff3-cmd */
NULL, /* merge options */
- NULL, /* prop_diff */
+ propchanges,
NULL, NULL, /* cancel_func + baton */
result_pool, scratch_pool));
- if (merge_outcome == svn_wc_merge_conflict)
+ /* If there are any conflicts to be stored, convert them into work items
+ * too. */
+ if (conflict_skel)
{
- svn_skel_t *work_item;
- svn_wc_conflict_version_t *original_version;
+ SVN_ERR(create_conflict_markers(work_items, local_abspath, db,
+ repos_relpath, conflict_skel,
+ old_version, new_version,
+ result_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
+ conflict_skel,
+ scratch_pool));
+ }
- if (conflict_skel)
- {
- original_version = svn_wc_conflict_version_dup(old_version,
- scratch_pool);
- original_version->path_in_repos = move_dst_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, db,
- moved_to_abspath,
- conflict_skel,
- scratch_pool,
- scratch_pool));
- *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
- }
+ if (merge_outcome == svn_wc_merge_conflict)
+ {
content_state = svn_wc_notify_state_conflicted;
}
else
@@ -253,7 +474,7 @@ update_working_file(svn_skel_t **work_it
svn_boolean_t is_locally_modified;
SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
- db, moved_to_abspath,
+ db, local_abspath,
FALSE /* exact_comparison */,
scratch_pool));
if (is_locally_modified)
@@ -262,70 +483,82 @@ update_working_file(svn_skel_t **work_it
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 = old_version->peg_rev;
- notify->revision = new_version->peg_rev;
- notify_func(notify_baton, notify, scratch_pool);
+ if (notify_func)
+ {
+ svn_wc_notify_t *notify;
+
+ notify = svn_wc_create_notify(local_abspath,
+ svn_wc_notify_update_update,
+ scratch_pool);
+ notify->kind = svn_node_file;
+ notify->content_state = content_state;
+ notify->prop_state = prop_state;
+ notify->old_revision = old_version->location_and_kind->peg_rev;
+ notify->revision = new_version->location_and_kind->peg_rev;
+ notify_func(notify_baton, notify, scratch_pool);
+ }
return SVN_NO_ERROR;
}
+/* Edit the file found at the move destination, which is initially at
+ * the old state. Merge the changes into the "working"/"actual" file.
+ */
static svn_error_t *
tc_editor_alter_file(void *baton,
const char *dst_relpath,
svn_revnum_t expected_move_dst_revision,
- apr_hash_t *props,
- const svn_checksum_t *move_src_checksum,
- svn_stream_t *post_update_contents,
+ apr_hash_t *new_props,
+ const svn_checksum_t *new_checksum,
+ svn_stream_t *new_contents,
apr_pool_t *scratch_pool)
{
struct tc_editor_baton *b = baton;
- const svn_checksum_t *move_dst_checksum;
const char *move_dst_repos_relpath;
svn_revnum_t move_dst_revision;
svn_kind_t move_dst_kind;
+ working_node_version_t old_version, new_version;
+ svn_boolean_t is_conflicted;
+
+ SVN_ERR(check_tree_conflict(&is_conflicted, b, dst_relpath, scratch_pool));
+ if (is_conflicted)
+ return SVN_NO_ERROR;
/* Get kind, revision, and checksum of the moved-here node. */
SVN_ERR(svn_wc__db_depth_get_info(NULL, &move_dst_kind, &move_dst_revision,
&move_dst_repos_relpath, NULL, NULL, NULL,
- NULL, NULL, &move_dst_checksum, NULL,
- NULL, b->wcroot, dst_relpath,
+ NULL, NULL, &old_version.checksum, NULL,
+ NULL, &old_version.props,
+ b->wcroot, dst_relpath,
relpath_depth(b->move_root_dst_relpath),
scratch_pool, scratch_pool));
SVN_ERR_ASSERT(move_dst_revision == expected_move_dst_revision);
SVN_ERR_ASSERT(move_dst_kind == svn_kind_file);
+ old_version.location_and_kind = b->old_version;
+ new_version.location_and_kind = b->new_version;
+
+ /* If new checksum is null that means no change; similarly props. */
+ new_version.checksum = new_checksum ? new_checksum : old_version.checksum;
+ new_version.props = new_props ? new_props : old_version.props;
+
/* ### TODO update revision etc. in NODES table */
/* Update file and prop contents if the update has changed them. */
- if (!svn_checksum_match(move_src_checksum, move_dst_checksum)
+ if (!svn_checksum_match(new_checksum, old_version.checksum)
/* ### || props have changed */)
{
- svn_boolean_t is_shadowed;
+ svn_skel_t *work_item;
- /* If the node is shadowed by a higher layer, we need to flag a
- * tree conflict and must not touch the working file. */
- SVN_ERR(check_shadowed_node(&is_shadowed,
- relpath_depth(b->move_root_dst_relpath),
- dst_relpath, b->wcroot));
- if (is_shadowed)
- {
- /* ### TODO flag tree conflict */
- }
- else
- SVN_ERR(update_working_file(b->work_items, dst_relpath,
- move_dst_repos_relpath,
- move_src_checksum, move_dst_checksum,
- b->old_version, b->new_version,
- b->wcroot, b->db,
- b->notify_func, b->notify_baton,
- b->result_pool, scratch_pool));
+ SVN_ERR(update_working_file(&work_item, dst_relpath,
+ move_dst_repos_relpath,
+ &old_version, &new_version,
+ b->wcroot, b->db,
+ b->notify_func, b->notify_baton,
+ b->result_pool, scratch_pool));
+ *b->work_items = svn_wc__wq_merge(*b->work_items, work_item,
+ b->result_pool);
}
return SVN_NO_ERROR;
@@ -348,7 +581,23 @@ tc_editor_delete(void *baton,
svn_revnum_t revision,
apr_pool_t *scratch_pool)
{
- return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+ struct tc_editor_baton *b = baton;
+ svn_sqlite__stmt_t *stmt;
+ int op_depth = relpath_depth(b->move_root_dst_relpath);
+
+ /* Deleting the ROWS is valid so long as we update the parent before
+ committing the transaction. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+ STMT_DELETE_WORKING_OP_DEPTH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", b->wcroot->wc_id, relpath, op_depth));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ /* Retract any base-delete. */
+ SVN_ERR(svn_wc__db_retract_parent_delete(b->wcroot, relpath, op_depth,
+ scratch_pool));
+
+ /* ### TODO check for, and flag, tree conflict */
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -387,18 +636,22 @@ 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->move_root_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);
+ if (b->notify_func)
+ {
+ svn_wc_notify_t *notify;
+
+ notify = svn_wc_create_notify(svn_dirent_join(b->wcroot->abspath,
+ b->move_root_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;
}
@@ -410,6 +663,13 @@ tc_editor_abort(void *baton,
return SVN_NO_ERROR;
}
+/* An editor.
+ *
+ * This editor will merge the edits into the 'actual' tree at
+ * MOVE_ROOT_DST_RELPATH (in struct tc_editor_baton),
+ * perhaps raising conflicts if necessary.
+ *
+ */
static const svn_editor_cb_many_t editor_ops = {
tc_editor_add_directory,
tc_editor_add_file,
@@ -429,6 +689,18 @@ static const svn_editor_cb_many_t editor
/*
* Driver code.
+ *
+ * The scenario is that a subtree has been locally moved, and then the base
+ * layer on the source side of the move has received an update to a new
+ * state. The destination subtree has not yet been updated, and still
+ * matches the pre-update state of the source subtree.
+ *
+ * The edit driver drives the receiver with the difference between the
+ * pre-update state (as found now at the move-destination) and the
+ * post-update state (found now at the move-source).
+ *
+ * We currently assume that both the pre-update and post-update states are
+ * single-revision.
*/
/* Set *OPERATION, *LOCAL_CHANGE, *INCOMING_CHANGE, *OLD_VERSION, *NEW_VERSION
@@ -442,8 +714,8 @@ get_tc_info(svn_wc_operation_t *operatio
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,
+ const char *src_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -488,14 +760,55 @@ get_tc_info(svn_wc_operation_t *operatio
const char *repos_relpath;
svn_revnum_t revision;
svn_node_kind_t node_kind;
+ svn_wc__db_status_t status;
+
+ /* The scan dance: read_info then scan_delete then base_get
+ or scan_addition. Use the internal/relpath functions
+ here? */
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision,
+ &repos_relpath, &repos_root_url,
+ &repos_uuid, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ db, src_abspath, result_pool,
+ scratch_pool));
+ if (status == svn_wc__db_status_deleted)
+ {
+ const char *base_del_abspath, *work_del_abspath;
+ SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
+ &work_del_abspath,
+ NULL, db, src_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR_ASSERT(base_del_abspath || work_del_abspath);
+ if (base_del_abspath)
+ {
+ 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, NULL,
+ db, src_abspath, result_pool,
+ scratch_pool));
+ }
+ else if (work_del_abspath)
+ {
+ work_del_abspath = svn_dirent_dirname(work_del_abspath,
+ scratch_pool);
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
+ &repos_root_url, &repos_uuid,
+ NULL, NULL, NULL,
+ &revision, NULL, NULL,
+ db, work_del_abspath,
+ scratch_pool, scratch_pool));
+ repos_relpath = svn_relpath_join(repos_relpath,
+ svn_dirent_skip_ancestor(work_del_abspath,
+ src_abspath),
+ scratch_pool);
+ }
+ }
- /* Construct 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,
@@ -519,6 +832,7 @@ get_tc_info(svn_wc_operation_t *operatio
*/
static svn_error_t *
update_moved_away_file(svn_editor_t *tc_editor,
+ svn_boolean_t add,
const char *src_relpath,
const char *dst_relpath,
const char *move_root_dst_relpath,
@@ -528,26 +842,35 @@ update_moved_away_file(svn_editor_t *tc_
apr_pool_t *scratch_pool)
{
svn_kind_t kind;
- svn_stream_t *post_update_contents;
- const svn_checksum_t *move_src_checksum;
-
+ svn_stream_t *new_contents;
+ const svn_checksum_t *new_checksum;
+ apr_hash_t *new_props;
+
/* 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,
- &move_src_checksum, NULL, NULL, db,
- svn_dirent_join(wcroot->abspath,
- src_relpath,
- scratch_pool),
+ &new_checksum, NULL, NULL, &new_props,
+ 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, move_src_checksum,
+ SVN_ERR(svn_wc__db_pristine_read(&new_contents, NULL, db,
+ wcroot->abspath, new_checksum,
scratch_pool, scratch_pool));
- SVN_ERR(svn_editor_alter_file(tc_editor, dst_relpath,
- move_root_dst_revision,
- NULL, /* ### TODO props */
- move_src_checksum,
- post_update_contents));
- SVN_ERR(svn_stream_close(post_update_contents));
+
+ if (add)
+ /* FIXME: editor API violation: missing svn_editor_alter_directory. */
+ SVN_ERR(svn_editor_add_file(tc_editor, dst_relpath,
+ new_checksum, new_contents,
+ apr_hash_make(scratch_pool), /* ### TODO props */
+ move_root_dst_revision));
+ else
+ SVN_ERR(svn_editor_alter_file(tc_editor, dst_relpath,
+ move_root_dst_revision,
+ new_props, new_checksum,
+ new_contents));
+
+ SVN_ERR(svn_stream_close(new_contents));
return SVN_NO_ERROR;
}
@@ -556,19 +879,45 @@ update_moved_away_file(svn_editor_t *tc_
*/
static svn_error_t *
update_moved_away_dir(svn_editor_t *tc_editor,
+ svn_boolean_t add,
const char *src_relpath,
const char *dst_relpath,
+ int src_op_depth,
const char *move_root_dst_relpath,
svn_revnum_t move_root_dst_revision,
svn_wc__db_t *db,
svn_wc__db_wcroot_t *wcroot,
apr_pool_t *scratch_pool)
{
- /* ### notify */
+ apr_hash_t *children_hash;
+ apr_array_header_t *new_children;
+ apr_hash_t *new_props;
+ const char *src_abspath = svn_dirent_join(wcroot->abspath,
+ src_relpath,
+ scratch_pool);
- /* ### update prop content if changed */
+ if (add)
+ {
+ /* ### TODO children and props */
+ SVN_ERR(svn_editor_add_directory(tc_editor, dst_relpath,
+ apr_array_make(scratch_pool, 0,
+ sizeof (const char *)),
+ apr_hash_make(scratch_pool),
+ move_root_dst_revision));
+ return SVN_NO_ERROR;
+ }
- /* ### update list of children if changed */
+ SVN_ERR(svn_wc__db_get_children_op_depth(&children_hash, wcroot,
+ src_relpath, src_op_depth,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_hash_keys(&new_children, children_hash, scratch_pool));
+
+ SVN_ERR(svn_wc__db_read_pristine_props(&new_props, db, src_abspath,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_editor_alter_directory(tc_editor, dst_relpath,
+ move_root_dst_revision,
+ new_children, new_props));
return SVN_NO_ERROR;
}
@@ -577,85 +926,169 @@ update_moved_away_dir(svn_editor_t *tc_e
*/
static svn_error_t *
update_moved_away_subtree(svn_editor_t *tc_editor,
+ svn_boolean_t add,
const char *src_relpath,
const char *dst_relpath,
+ int src_op_depth,
const char *move_root_dst_relpath,
svn_revnum_t move_root_dst_revision,
svn_wc__db_t *db,
svn_wc__db_wcroot_t *wcroot,
apr_pool_t *scratch_pool)
{
- const apr_array_header_t *children;
+ apr_hash_t *src_children, *dst_children;
apr_pool_t *iterpool;
- int i;
+ apr_hash_index_t *hi;
- SVN_ERR(update_moved_away_dir(tc_editor, src_relpath, dst_relpath,
- move_root_dst_relpath,
+ SVN_ERR(update_moved_away_dir(tc_editor, add, src_relpath, dst_relpath,
+ src_op_depth, move_root_dst_relpath,
move_root_dst_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));
+ SVN_ERR(svn_wc__db_get_children_op_depth(&src_children, wcroot,
+ src_relpath, src_op_depth,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_get_children_op_depth(&dst_children, wcroot,
+ dst_relpath,
+ relpath_depth(move_root_dst_relpath),
+ scratch_pool, scratch_pool));
iterpool = svn_pool_create(scratch_pool);
- for (i = 0; i < children->nelts; i++)
+ for (hi = apr_hash_first(scratch_pool, src_children);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *src_name = svn__apr_hash_index_key(hi);
+ svn_kind_t *src_kind = svn__apr_hash_index_val(hi);
+ svn_kind_t *dst_kind = apr_hash_get(dst_children, src_name,
+ APR_HASH_KEY_STRING);
+ svn_boolean_t is_add = FALSE;
+ const char *child_src_relpath, *child_dst_relpath;
+
+ svn_pool_clear(iterpool);
+
+ child_src_relpath = svn_relpath_join(src_relpath, src_name, iterpool);
+ child_dst_relpath = svn_relpath_join(dst_relpath, src_name, iterpool);
+
+ if (!dst_kind || (*src_kind != *dst_kind))
+ {
+ is_add = TRUE;
+ if (dst_kind)
+ /* FIXME:editor API violation:missing svn_editor_alter_directory. */
+ SVN_ERR(svn_editor_delete(tc_editor, child_dst_relpath,
+ move_root_dst_revision));
+ }
+
+ if (*src_kind == svn_kind_file || *src_kind == svn_kind_symlink)
+ {
+ SVN_ERR(update_moved_away_file(tc_editor, is_add,
+ child_src_relpath,
+ child_dst_relpath,
+ move_root_dst_relpath,
+ move_root_dst_revision,
+ db, wcroot, iterpool));
+ }
+ else if (*src_kind == svn_kind_dir)
+ {
+ SVN_ERR(update_moved_away_subtree(tc_editor, is_add,
+ child_src_relpath,
+ child_dst_relpath,
+ src_op_depth,
+ move_root_dst_relpath,
+ move_root_dst_revision,
+ db, wcroot, iterpool));
+ }
+ else
+ ; /* ### TODO */
+
+ apr_hash_set(dst_children, src_name, APR_HASH_KEY_STRING, NULL);
+ }
+ for (hi = apr_hash_first(scratch_pool, dst_children);
+ hi;
+ hi = apr_hash_next(hi))
{
- const char *child_src_relpath;
- svn_kind_t child_kind;
- const char *child_dst_op_root_relpath;
+ const char *dst_name = svn__apr_hash_index_key(hi);
const char *child_dst_relpath;
svn_pool_clear(iterpool);
+ child_dst_relpath = svn_relpath_join(dst_relpath, dst_name, 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_root_dst_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_root_dst_relpath,
- move_root_dst_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_root_dst_relpath,
- move_root_dst_revision,
- db, wcroot, iterpool));
+ /* FIXME: editor API violation: missing svn_editor_alter_directory. */
+ SVN_ERR(svn_editor_delete(tc_editor, child_dst_relpath,
+ move_root_dst_revision));
}
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-/* ### Drive TC_EDITOR so as to ...
+/* Update the single op-depth layer in the move destination subtree
+ rooted at DST_RELPATH to make it match the move source subtree
+ rooted at SRC_RELPATH. */
+static svn_error_t *
+replace_moved_layer(const char *src_relpath,
+ const char *dst_relpath,
+ int src_op_depth,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ int dst_op_depth = relpath_depth(dst_relpath);
+
+ /* Replace entire subtree at one op-depth. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_LOCAL_RELPATH_OP_DEPTH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ src_relpath, src_op_depth));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ svn_error_t *err;
+ svn_sqlite__stmt_t *stmt2;
+ const char *src_cp_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+ const char *dst_cp_relpath
+ = svn_relpath_join(dst_relpath,
+ svn_relpath_skip_ancestor(src_relpath,
+ src_cp_relpath),
+ scratch_pool);
+
+ err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_COPY_NODE_MOVE);
+ if (!err)
+ err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
+ src_cp_relpath, src_op_depth,
+ dst_cp_relpath, dst_op_depth,
+ svn_relpath_dirname(dst_cp_relpath,
+ scratch_pool));
+ if (!err)
+ err = svn_sqlite__step_done(stmt2);
+ if (err)
+ return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ return SVN_NO_ERROR;
+}
+
+/* Transfer changes from the move source to the move destination.
+ *
+ * Drive the editor TC_EDITOR with the difference between DST_RELPATH
+ * (at its own op-depth) and SRC_RELPATH (at op-depth zero).
+ *
+ * Then update the single op-depth layer in the move destination subtree
+ * rooted at DST_RELPATH to make it match the move source subtree
+ * rooted at SRC_RELPATH.
+ *
+ * ### And the other params?
*/
static svn_error_t *
drive_tree_conflict_editor(svn_editor_t *tc_editor,
const char *src_relpath,
const char *dst_relpath,
+ int src_op_depth,
svn_wc_operation_t operation,
svn_wc_conflict_reason_t local_change,
svn_wc_conflict_action_t incoming_change,
@@ -680,40 +1113,36 @@ drive_tree_conflict_editor(svn_editor_t
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
+ /* 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.
- */
+ * 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,
+ SVN_ERR(update_moved_away_file(tc_editor, FALSE, 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,
+ SVN_ERR(update_moved_away_subtree(tc_editor, FALSE,
+ src_relpath, dst_relpath,
+ src_op_depth,
dst_relpath, old_version->peg_rev,
db, wcroot, scratch_pool));
SVN_ERR(svn_editor_complete(tc_editor));
+ SVN_ERR(replace_moved_layer(src_relpath, dst_relpath, src_op_depth,
+ db, wcroot, scratch_pool));
+
return SVN_NO_ERROR;
}
struct update_moved_away_conflict_victim_baton {
svn_skel_t **work_items;
- const char *victim_relpath;
+ svn_wc__db_t *db;
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;
@@ -732,21 +1161,22 @@ update_moved_away_conflict_victim(void *
struct update_moved_away_conflict_victim_baton *b = baton;
svn_editor_t *tc_editor;
struct tc_editor_baton *tc_editor_baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
/* ### assumes wc write lock already held */
/* Construct editor baton. */
tc_editor_baton = apr_pcalloc(scratch_pool, sizeof(*tc_editor_baton));
- tc_editor_baton->move_root_src_relpath = b->victim_relpath;
+ tc_editor_baton->move_root_src_relpath = victim_relpath;
SVN_ERR(svn_wc__db_scan_deletion_internal(
NULL, &tc_editor_baton->move_root_dst_relpath, NULL, NULL,
- wcroot, b->victim_relpath, scratch_pool, scratch_pool));
+ wcroot, victim_relpath, scratch_pool, scratch_pool));
if (tc_editor_baton->move_root_dst_relpath == NULL)
return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
_("The node '%s' has not been moved away"),
svn_dirent_local_style(
- svn_dirent_join(wcroot->abspath,
- b->victim_relpath,
+ svn_dirent_join(wcroot->abspath, victim_relpath,
scratch_pool),
scratch_pool));
tc_editor_baton->old_version= b->old_version;
@@ -758,6 +1188,23 @@ update_moved_away_conflict_victim(void *
tc_editor_baton->notify_baton = b->notify_baton;
tc_editor_baton->result_pool = b->result_pool;
+ /* ### TODO get from svn_wc__db_scan_deletion_internal? */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_NODE_INFO));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, victim_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ tc_editor_baton->src_op_depth = svn_sqlite__column_int(stmt, 0);
+ SVN_ERR(svn_sqlite__reset(stmt));
+ if (!have_row)
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("'%s' is not deleted"),
+ svn_dirent_local_style(
+ svn_dirent_join(wcroot->abspath, victim_relpath,
+ scratch_pool),
+ scratch_pool));
/* Create the editor... */
SVN_ERR(svn_editor_create(&tc_editor, tc_editor_baton,
b->cancel_func, b->cancel_baton,
@@ -768,6 +1215,7 @@ update_moved_away_conflict_victim(void *
SVN_ERR(drive_tree_conflict_editor(tc_editor,
tc_editor_baton->move_root_src_relpath,
tc_editor_baton->move_root_dst_relpath,
+ tc_editor_baton->src_op_depth,
b->operation,
b->local_change, b->incoming_change,
tc_editor_baton->old_version,
@@ -782,8 +1230,8 @@ update_moved_away_conflict_victim(void *
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,
+ const char *victim_abspath,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
@@ -794,15 +1242,11 @@ svn_wc__db_update_moved_away_conflict_vi
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(get_tc_info(&b.operation, &b.local_change, &b.incoming_change,
+ &b.old_version, &b.new_version,
+ db, victim_abspath,
+ scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
db, victim_abspath,
@@ -810,12 +1254,6 @@ svn_wc__db_update_moved_away_conflict_vi
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;
Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_util.c?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_util.c Thu Dec 27 04:03:49 2012
@@ -153,8 +153,8 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
/* Some helpful transaction helpers.
- Instead of directly using SQLite transactions, these wrappers take care of
- simple cases by allowing consumers to worry about wrapping the wcroot and
+ Instead of directly using SQLite transactions, these wrappers
+ relieve the consumer from the need to wrap the wcroot and
local_relpath, which are almost always used within the transaction.
This also means if we later want to implement some wc_db-specific txn
Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.c?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.c Thu Dec 27 04:03:49 2012
@@ -148,7 +148,7 @@ run_base_remove(svn_wc__db_t *db,
¬_present_rev, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL,
+ NULL, NULL, NULL,
db, local_abspath,
scratch_pool, scratch_pool));
}
Modified: subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.h?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_wc/workqueue.h Thu Dec 27 04:03:49 2012
@@ -93,8 +93,8 @@ svn_wc__wq_run(svn_wc__db_t *db,
/* Set *WORK_ITEM to a new work item that will install the working
copy file at LOCAL_ABSPATH. If USE_COMMIT_TIMES is TRUE, then the newly
installed file will use the nodes CHANGE_DATE for the file timestamp.
- If RECORD_FILEINFO is TRUE, then the resulting LAST_MOD_TIME and
- TRANSLATED_SIZE will be recorded in the database.
+ If RECORD_FILEINFO is TRUE, then the resulting RECORDED_TIME and
+ RECORDED_SIZE will be recorded in the database.
If SOURCE_ABSPATH is NULL, then the pristine contents will be installed
(with appropriate translation). If SOURCE_ABSPATH is not NULL, then it
Modified: subversion/branches/javahl-ra/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/mod_dav_svn/dav_svn.h?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/javahl-ra/subversion/mod_dav_svn/dav_svn.h Thu Dec 27 04:03:49 2012
@@ -52,6 +52,12 @@ extern "C" {
/* a pool-key for the shared dav_svn_root used by autoversioning */
#define DAV_SVN__AUTOVERSIONING_ACTIVITY "svn-autoversioning-activity"
+/* Option values for SVNAllowBulkUpdates */
+typedef enum dav_svn__bulk_upd_conf {
+ CONF_BULKUPD_ON,
+ CONF_BULKUPD_OFF,
+ CONF_BULKUPD_PREFER
+} dav_svn__bulk_upd_conf;
/* dav_svn_repos
*
@@ -110,7 +116,7 @@ typedef struct dav_svn_repos {
svn_boolean_t autoversioning;
/* Whether bulk updates are allowed for this repository. */
- svn_boolean_t bulk_updates;
+ dav_svn__bulk_upd_conf bulk_updates;
/* Whether HTTP protocol version 2 is allowed to be used. */
svn_boolean_t v2_protocol;
@@ -302,7 +308,7 @@ const char *dav_svn__get_fs_parent_path(
svn_boolean_t dav_svn__get_autoversioning_flag(request_rec *r);
/* for the repository referred to by this request, are bulk updates allowed? */
-svn_boolean_t dav_svn__get_bulk_updates_flag(request_rec *r);
+dav_svn__bulk_upd_conf dav_svn__get_bulk_updates_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);
Modified: subversion/branches/javahl-ra/subversion/mod_dav_svn/mirror.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/mod_dav_svn/mirror.c?rev=1426116&r1=1426115&r2=1426116&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/mod_dav_svn/mirror.c (original)
+++ subversion/branches/javahl-ra/subversion/mod_dav_svn/mirror.c Thu Dec 27 04:03:49 2012
@@ -39,12 +39,17 @@
URI_SEGMENT is the URI bits relative to the repository root (but if
non-empty, *does* have a leading slash delimiter).
MASTER_URI and URI_SEGMENT are not URI-encoded. */
-static void proxy_request_fixup(request_rec *r,
- const char *master_uri,
- const char *uri_segment)
+static int proxy_request_fixup(request_rec *r,
+ const char *master_uri,
+ const char *uri_segment)
{
- assert((uri_segment[0] == '\0')
- || (uri_segment[0] == '/'));
+ if (uri_segment[0] != '\0' && uri_segment[0] != '/')
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, SVN_ERR_BAD_CONFIG_VALUE, r,
+ "Invalid URI segment '%s' in slave fixup",
+ uri_segment);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
r->proxyreq = PROXYREQ_REVERSE;
r->uri = r->unparsed_uri;
@@ -67,6 +72,7 @@ static void proxy_request_fixup(request_
ap_add_output_filter("LocationRewrite", NULL, r, r->connection);
ap_add_output_filter("ReposRewrite", NULL, r, r->connection);
ap_add_input_filter("IncomingRewrite", NULL, r, r->connection);
+ return OK;
}
@@ -101,8 +107,10 @@ int dav_svn__proxy_request_fixup(request
"/txn/", (char *)NULL))
|| ap_strstr_c(seg, apr_pstrcat(r->pool, special_uri,
"/txr/", (char *)NULL))) {
+ int rv;
seg += strlen(root_dir);
- proxy_request_fixup(r, master_uri, seg);
+ rv = proxy_request_fixup(r, master_uri, seg);
+ if (rv) return rv;
}
}
return OK;
@@ -116,8 +124,10 @@ int dav_svn__proxy_request_fixup(request
r->method_number == M_LOCK ||
r->method_number == M_UNLOCK ||
ap_strstr_c(seg, special_uri))) {
+ int rv;
seg += strlen(root_dir);
- proxy_request_fixup(r, master_uri, seg);
+ rv = proxy_request_fixup(r, master_uri, seg);
+ if (rv) return rv;
return OK;
}
}