You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/12/04 03:26:43 UTC
svn commit: r1416748 [3/5] - in /subversion/branches/ev2-export: ./
build/ac-macros/ build/generator/ subversion/bindings/cxxhl/
subversion/bindings/swig/perl/native/ subversion/include/
subversion/include/private/ subversion/libsvn_client/ subversion/...
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c Tue Dec 4 02:26:18 2012
@@ -610,8 +610,8 @@ file_diff(struct edit_baton *eb,
apr_hash_t *baseprops;
/* Get svn:mime-type from pristine props (in BASE or WORKING) of PATH. */
- SVN_ERR(svn_wc__get_pristine_props(&baseprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&baseprops, db, local_abspath,
+ scratch_pool, scratch_pool));
if (baseprops)
base_mimetype = get_prop_mimetype(baseprops);
else
@@ -731,8 +731,8 @@ file_diff(struct edit_baton *eb,
|| status == svn_wc__db_status_copied
|| status == svn_wc__db_status_moved_here);
- SVN_ERR(svn_wc__get_pristine_props(&baseprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&baseprops, db, local_abspath,
+ scratch_pool, scratch_pool));
/* baseprops will be NULL for added nodes */
if (!baseprops)
@@ -984,8 +984,8 @@ report_wc_file_as_added(struct edit_bato
emptyprops = apr_hash_make(scratch_pool);
if (eb->use_text_base)
- SVN_ERR(svn_wc__get_pristine_props(&wcprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&wcprops, db, local_abspath,
+ scratch_pool, scratch_pool));
else
SVN_ERR(svn_wc__get_actual_props(&wcprops, db, local_abspath,
scratch_pool, scratch_pool));
@@ -996,16 +996,21 @@ report_wc_file_as_added(struct edit_bato
if (eb->use_text_base)
- SVN_ERR(get_pristine_file(&source_file, db, local_abspath,
- FALSE, scratch_pool, scratch_pool));
+ {
+ SVN_ERR(get_pristine_file(&source_file, db, local_abspath,
+ FALSE, scratch_pool, scratch_pool));
+ translated_file = source_file; /* No translation needed */
+ }
else
- source_file = local_abspath;
+ {
+ source_file = local_abspath;
- SVN_ERR(svn_wc__internal_translated_file(
+ SVN_ERR(svn_wc__internal_translated_file(
&translated_file, source_file, db, local_abspath,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
eb->cancel_func, eb->cancel_baton,
scratch_pool, scratch_pool));
+ }
SVN_ERR(eb->callbacks->file_added(NULL, NULL, NULL,
path,
@@ -1054,8 +1059,8 @@ report_wc_directory_as_added(struct edit
eb->changelist_hash, scratch_pool))
{
if (eb->use_text_base)
- SVN_ERR(svn_wc__get_pristine_props(&wcprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&wcprops, db, local_abspath,
+ scratch_pool, scratch_pool));
else
SVN_ERR(svn_wc__get_actual_props(&wcprops, db, local_abspath,
scratch_pool, scratch_pool));
@@ -1227,8 +1232,9 @@ delete_entry(const char *path,
SVN_ERR(get_pristine_file(&textbase, db, local_abspath,
eb->use_text_base, pool, pool));
- SVN_ERR(svn_wc__get_pristine_props(&baseprops, eb->db, local_abspath,
- pool, pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&baseprops,
+ eb->db, local_abspath,
+ pool, pool));
base_mimetype = get_prop_mimetype(baseprops);
SVN_ERR(eb->callbacks->file_deleted(NULL, NULL, path,
@@ -1349,9 +1355,10 @@ close_directory(void *dir_baton,
{
if (db->eb->use_text_base)
{
- SVN_ERR(svn_wc__get_pristine_props(&originalprops,
- eb->db, db->local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&originalprops,
+ eb->db, db->local_abspath,
+ scratch_pool,
+ scratch_pool));
}
else
{
@@ -1362,9 +1369,9 @@ close_directory(void *dir_baton,
scratch_pool, scratch_pool));
/* Load the BASE and repository directory properties. */
- SVN_ERR(svn_wc__get_pristine_props(&base_props,
- eb->db, db->local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_base_get_props(&base_props,
+ eb->db, db->local_abspath,
+ scratch_pool, scratch_pool));
repos_props = apply_propchanges(base_props, db->propchanges);
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/diff_local.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/diff_local.c Tue Dec 4 02:26:18 2012
@@ -239,8 +239,8 @@ file_diff(struct diff_baton *eb,
/* We show a deletion of what was actually deleted */
SVN_ERR_ASSERT(status == svn_wc__db_status_deleted);
- SVN_ERR(svn_wc__get_pristine_props(&del_props, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&del_props, db, local_abspath,
+ scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_read_pristine_info(NULL, NULL, NULL, NULL, NULL,
NULL, &del_checksum, NULL,
@@ -513,9 +513,7 @@ diff_status_callback(void *baton,
/* Report the prop change. */
/* ### This case should probably be extended for git-diff, but this
is what the old diff code provided */
- if (status->node_status == svn_wc_status_deleted
- || status->node_status == svn_wc_status_replaced
- || status->prop_status == svn_wc_status_modified)
+ if (status->prop_status == svn_wc_status_modified)
{
apr_array_header_t *propchanges;
apr_hash_t *baseprops;
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/externals.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/externals.c Tue Dec 4 02:26:18 2012
@@ -164,10 +164,8 @@ svn_wc_parse_externals_description3(apr_
apr_pool_t *pool)
{
int i;
- unsigned int len;
apr_array_header_t *externals = NULL;
apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
- apr_hash_t *duplicate_check = apr_hash_make(pool);
const char *parent_directory_display = svn_path_is_url(parent_directory) ?
parent_directory : svn_dirent_local_style(parent_directory, pool);
@@ -332,21 +330,6 @@ svn_wc_parse_externals_description3(apr_
item->url = svn_dirent_canonicalize(item->url, pool);
}
- /* Has the same WC target path already been mentioned in this prop? */
- len = apr_hash_count(duplicate_check);
- apr_hash_set(duplicate_check, item->target_dir, APR_HASH_KEY_STRING, "");
- if (len == apr_hash_count(duplicate_check))
- {
- /* Hashtable length is unchanged. This must be a duplicate. */
- return svn_error_createf
- (SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
- _("Invalid %s property on '%s': "
- "target '%s' appears more than once"),
- SVN_PROP_EXTERNALS,
- parent_directory_display,
- item->target_dir);
- }
-
if (externals)
APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item;
}
@@ -357,6 +340,53 @@ svn_wc_parse_externals_description3(apr_
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets,
+ apr_array_header_t *externals,
+ apr_pool_t *pool,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ unsigned int len;
+ unsigned int len2;
+ const char *target;
+ apr_hash_t *targets = apr_hash_make(scratch_pool);
+ apr_hash_t *targets2 = NULL;
+ *duplicate_targets = NULL;
+
+ for (i = 0; i < externals->nelts; i++)
+ {
+ target = APR_ARRAY_IDX(externals, i,
+ svn_wc_external_item2_t*)->target_dir;
+ len = apr_hash_count(targets);
+ apr_hash_set(targets, target, APR_HASH_KEY_STRING, "");
+ if (len == apr_hash_count(targets))
+ {
+ /* Hashtable length is unchanged. This must be a duplicate. */
+
+ /* Collapse multiple duplicates of the same target by using a second
+ * hash layer. */
+ if (! targets2)
+ targets2 = apr_hash_make(scratch_pool);
+ len2 = apr_hash_count(targets2);
+ apr_hash_set(targets2, target, APR_HASH_KEY_STRING, "");
+ if (len2 < apr_hash_count(targets2))
+ {
+ /* The second hash list just got bigger, i.e. this target has
+ * not been counted as duplicate before. */
+ if (! *duplicate_targets)
+ {
+ *duplicate_targets = apr_array_make(
+ pool, 1, sizeof(svn_wc_external_item2_t*));
+ }
+ APR_ARRAY_PUSH((*duplicate_targets), const char *) = target;
+ }
+ /* Else, this same target has already been recorded as a duplicate,
+ * don't count it again. */
+ }
+ }
+ return SVN_NO_ERROR;
+}
struct edit_baton
{
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/props.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/props.c Tue Dec 4 02:26:18 2012
@@ -280,8 +280,8 @@ svn_wc__perform_props_merge(svn_wc_notif
}
if (had_props)
- SVN_ERR(svn_wc__get_pristine_props(&pristine_props, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props, db, local_abspath,
+ scratch_pool, scratch_pool));
if (pristine_props == NULL)
pristine_props = apr_hash_make(scratch_pool);
@@ -1513,13 +1513,13 @@ svn_wc__prop_retrieve_recursive(apr_hash
}
svn_error_t *
-svn_wc__get_pristine_props(apr_hash_t **props,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_wc_get_pristine_props(apr_hash_t **props,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- svn_wc__db_status_t status;
+ svn_error_t *err;
SVN_ERR_ASSERT(props != NULL);
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1527,60 +1527,23 @@ svn_wc__get_pristine_props(apr_hash_t **
/* Certain node stats do not have properties defined on them. Check the
state, and return NULL for these situations. */
- SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
- if (status == svn_wc__db_status_added)
- {
- /* Resolve the status. copied and moved_here arrive with properties,
- while a simple add does not. */
- SVN_ERR(svn_wc__db_scan_addition(&status, NULL,
- NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
- }
- if (status == svn_wc__db_status_added
-#if 0
- /* ### the update editor needs to fetch properties while the directory
- ### is still marked incomplete */
- || status == svn_wc__db_status_incomplete
-#endif
- || status == svn_wc__db_status_excluded
- || status == svn_wc__db_status_server_excluded
- || status == svn_wc__db_status_not_present)
- {
- *props = NULL;
- return SVN_NO_ERROR;
- }
+ err = svn_wc__db_read_pristine_props(props, wc_ctx->db, local_abspath,
+ result_pool, scratch_pool);
- /* status: normal, moved_here, copied, deleted */
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ return svn_error_trace(err);
- /* After the above checks, these pristines should always be present. */
- return svn_error_trace(
- svn_wc__db_read_pristine_props(props, db, local_abspath,
- result_pool, scratch_pool));
-}
+ svn_error_clear(err);
+ /* Documented behavior is to set *PROPS to NULL */
+ *props = NULL;
+ }
-svn_error_t *
-svn_wc_get_pristine_props(apr_hash_t **props,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- return svn_error_trace(svn_wc__get_pristine_props(props,
- wc_ctx->db,
- local_abspath,
- result_pool,
- scratch_pool));
+ return SVN_NO_ERROR;
}
-
svn_error_t *
svn_wc_prop_get2(const svn_string_t **value,
svn_wc_context_t *wc_ctx,
@@ -1590,6 +1553,7 @@ svn_wc_prop_get2(const svn_string_t **va
apr_pool_t *scratch_pool)
{
enum svn_prop_kind kind = svn_property_kind2(name);
+ svn_error_t *err;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1600,8 +1564,18 @@ svn_wc_prop_get2(const svn_string_t **va
_("Property '%s' is an entry property"), name);
}
- SVN_ERR(svn_wc__internal_propget(value, wc_ctx->db, local_abspath, name,
- result_pool, scratch_pool));
+ err = svn_wc__internal_propget(value, wc_ctx->db, local_abspath, name,
+ result_pool, scratch_pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ /* Documented behavior is to set *VALUE to NULL */
+ *value = NULL;
+ }
return SVN_NO_ERROR;
}
@@ -1616,35 +1590,15 @@ svn_wc__internal_propget(const svn_strin
{
apr_hash_t *prophash = NULL;
enum svn_prop_kind kind = svn_property_kind2(name);
- svn_boolean_t hidden;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(kind != svn_prop_entry_kind);
- /* This returns SVN_ERR_WC_PATH_NOT_FOUND for unversioned paths for us */
- SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, scratch_pool));
- if (hidden)
- {
- /* The node is not present, or not really "here". Therefore, the
- property is not present. */
- *value = NULL;
- return SVN_NO_ERROR;
- }
-
if (kind == svn_prop_wc_kind)
{
- svn_error_t *err;
- /* If no dav cache can be found, just set VALUE to NULL (for
- compatibility with pre-WC-NG code). */
- err = svn_wc__db_base_get_dav_cache(&prophash, db, local_abspath,
- result_pool, scratch_pool);
- if (err && (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND))
- {
- *value = NULL;
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- SVN_ERR_W(err, _("Failed to load properties"));
+ SVN_ERR_W(svn_wc__db_base_get_dav_cache(&prophash, db, local_abspath,
+ result_pool, scratch_pool),
+ _("Failed to load properties"));
}
else
{
@@ -1665,47 +1619,38 @@ svn_wc__internal_propget(const svn_strin
/* The special Subversion properties are not valid for all node kinds.
Return an error if NAME is an invalid Subversion property for PATH which
- is of kind NODE_KIND. */
+ is of kind NODE_KIND. NAME must be in the "svn:" name space.
+
+ Note that we only disallow the property if we're sure it's one that
+ already has a meaning for a different node kind. We don't disallow
+ setting an *unknown* svn: prop here, at this level; a higher level
+ should disallow that if desired.
+ */
static svn_error_t *
validate_prop_against_node_kind(const char *name,
const char *path,
svn_node_kind_t node_kind,
apr_pool_t *pool)
{
-
- const char *file_prohibit[] = { SVN_PROP_IGNORE,
- SVN_PROP_EXTERNALS,
- SVN_PROP_INHERITABLE_AUTO_PROPS,
- SVN_PROP_INHERITABLE_IGNORES,
- NULL };
- const char *dir_prohibit[] = { SVN_PROP_EXECUTABLE,
- SVN_PROP_KEYWORDS,
- SVN_PROP_EOL_STYLE,
- SVN_PROP_MIME_TYPE,
- SVN_PROP_NEEDS_LOCK,
- NULL };
- const char **node_kind_prohibit;
const char *path_display
= svn_path_is_url(path) ? path : svn_dirent_local_style(path, pool);
switch (node_kind)
{
case svn_node_dir:
- node_kind_prohibit = dir_prohibit;
- while (*node_kind_prohibit)
- if (strcmp(name, *node_kind_prohibit++) == 0)
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("Cannot set '%s' on a directory ('%s')"),
- name, path_display);
+ if (! svn_prop_is_known_svn_dir_prop(name)
+ && svn_prop_is_known_svn_file_prop(name))
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Cannot set '%s' on a directory ('%s')"),
+ name, path_display);
break;
case svn_node_file:
- node_kind_prohibit = file_prohibit;
- while (*node_kind_prohibit)
- if (strcmp(name, *node_kind_prohibit++) == 0)
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("Cannot set '%s' on a file ('%s')"),
- name,
- path_display);
+ if (! svn_prop_is_known_svn_file_prop(name)
+ && svn_prop_is_known_svn_dir_prop(name))
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Cannot set '%s' on a file ('%s')"),
+ name,
+ path_display);
break;
default:
return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
@@ -1787,17 +1732,14 @@ validate_eol_prop_against_file(const cha
err = getter(NULL, translating_stream, getter_baton, pool);
- if (!err)
- err = svn_stream_close(translating_stream);
+ err = svn_error_compose_create(err, svn_stream_close(translating_stream));
if (err && err->apr_err == SVN_ERR_IO_INCONSISTENT_EOL)
return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, err,
_("File '%s' has inconsistent newlines"),
path_display);
- else if (err)
- return err;
- return SVN_NO_ERROR;
+ return svn_error_trace(err);
}
static svn_error_t *
@@ -1952,6 +1894,7 @@ do_propset(svn_wc__db_t *db,
notify_action,
scratch_pool);
notify->prop_name = name;
+ notify->kind = kind;
(*notify_func)(notify_baton, notify, scratch_pool);
}
@@ -1988,7 +1931,7 @@ propset_walk_cb(const char *local_abspat
err = do_propset(wb->db, local_abspath, kind, wb->propname, wb->propval,
wb->force, wb->notify_func, wb->notify_baton, scratch_pool);
if (err && (err->apr_err == SVN_ERR_ILLEGAL_TARGET
- || err->apr_err == SVN_ERR_WC_INVALID_SCHEDULE))
+ || err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS))
{
svn_error_clear(err);
err = SVN_NO_ERROR;
@@ -2012,9 +1955,8 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
apr_pool_t *scratch_pool)
{
enum svn_prop_kind prop_kind = svn_property_kind2(name);
- svn_wc__db_status_t status;
svn_kind_t kind;
- const char *dir_abspath;
+ svn_wc__db_t *db = wc_ctx->db;
/* we don't do entry properties here */
if (prop_kind == svn_prop_entry_kind)
@@ -2029,38 +1971,34 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
name, value, scratch_pool));
}
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, FALSE,
+ scratch_pool));
+
/* We have to do this little DIR_ABSPATH dance for backwards compat.
But from 1.7 onwards, all locks are of infinite depth, and from 1.6
backward we never call this API with depth > empty, so we only need
to do the write check once per call, here (and not for every node in
- the node walker). */
- /* Get the node status for this path. */
- SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- wc_ctx->db, local_abspath,
- scratch_pool, scratch_pool));
+ the node walker).
- if (status != svn_wc__db_status_normal
- && status != svn_wc__db_status_added
- && status != svn_wc__db_status_incomplete)
- return svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, NULL,
- _("Can't set properties on '%s':"
- " invalid status for updating properties."),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
+ ### Note that we could check for a write lock on local_abspath first
+ ### if we would want to. And then justy check for kind if that fails.
+ ### ... but we need kind for the "svn:" property checks anyway */
+ {
+ const char *dir_abspath;
- if (kind == svn_kind_dir)
- dir_abspath = local_abspath;
- else
- dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+ if (kind == svn_kind_dir)
+ dir_abspath = local_abspath;
+ else
+ dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
+ /* Verify that we're holding this directory's write lock. */
+ SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
+ }
if (depth == svn_depth_empty || kind != svn_kind_dir)
{
apr_hash_t *changelist_hash = NULL;
+ svn_error_t *err;
if (changelist_filter && changelist_filter->nelts)
SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter,
@@ -2070,12 +2008,23 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
changelist_hash, scratch_pool))
return SVN_NO_ERROR;
- SVN_ERR(do_propset(wc_ctx->db, local_abspath,
+ err = do_propset(wc_ctx->db, local_abspath,
kind == svn_kind_dir
? svn_node_dir
: svn_node_file,
name, value, skip_checks,
- notify_func, notify_baton, scratch_pool));
+ notify_func, notify_baton, scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ {
+ err = svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, err,
+ _("Can't set properties on '%s':"
+ " invalid status for updating properties."),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
+
+ SVN_ERR(err);
}
else
{
@@ -2168,9 +2117,34 @@ svn_wc_canonicalize_svn_prop(const svn_s
an svn:externals line. As it happens, our parse code
checks for this, so all we have to is invoke it --
we're not interested in the parsed result, only in
- whether or the parsing errored. */
- SVN_ERR(svn_wc_parse_externals_description3
- (NULL, path, propval->data, FALSE, pool));
+ whether or not the parsing errored. */
+ apr_array_header_t *externals = NULL;
+ apr_array_header_t *duplicate_targets = NULL;
+ SVN_ERR(svn_wc_parse_externals_description3(&externals, path,
+ propval->data, FALSE,
+ /*scratch_*/pool));
+ SVN_ERR(svn_wc__externals_find_target_dups(&duplicate_targets,
+ externals,
+ /*scratch_*/pool,
+ /*scratch_*/pool));
+ if (duplicate_targets && duplicate_targets->nelts > 0)
+ {
+ const char *more_str = "";
+ if (duplicate_targets->nelts > 1)
+ {
+ more_str = apr_psprintf(/*scratch_*/pool,
+ _(" (%d more duplicate targets found)"),
+ duplicate_targets->nelts - 1);
+ }
+ return svn_error_createf(
+ SVN_ERR_WC_DUPLICATE_EXTERNALS_TARGET, NULL,
+ _("Invalid %s property on '%s': "
+ "target '%s' appears more than once%s"),
+ SVN_PROP_EXTERNALS,
+ svn_dirent_local_style(path, pool),
+ APR_ARRAY_IDX(duplicate_targets, 0, const char*),
+ more_str);
+ }
}
}
else if (strcmp(propname, SVN_PROP_KEYWORDS) == 0)
@@ -2338,132 +2312,6 @@ svn_wc__has_magic_property(const apr_arr
return FALSE;
}
-/* Remove all prop name value pairs from PROP_HASH where the property
- name is not PROPNAME. */
-static void
-filter_unwanted_props(apr_hash_t *prop_hash,
- const char * propname,
- apr_pool_t *scratch_pool)
-{
- apr_hash_index_t *hi;
-
- for (hi = apr_hash_first(scratch_pool, prop_hash);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *ipropname = svn__apr_hash_index_key(hi);
-
- if (strcmp(ipropname, propname) != 0)
- apr_hash_set(prop_hash, ipropname, APR_HASH_KEY_STRING, NULL);
- }
- return;
-}
-
-svn_error_t *
-svn_wc__internal_get_iprops(apr_array_header_t **inherited_props,
- svn_wc__db_t *db,
- const char *local_abspath,
- const char *propname,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- int i;
- apr_array_header_t *cached_iprops = NULL;
- const char *parent_abspath = local_abspath;
- svn_boolean_t is_wc_root = FALSE;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- SVN_ERR_ASSERT(inherited_props);
- *inherited_props = apr_array_make(result_pool, 1,
- sizeof(svn_prop_inherited_item_t *));
-
- /* Walk up to the root of the WC looking for inherited properties. When we
- reach the WC root also check for cached inherited properties. */
- while (TRUE)
- {
- apr_hash_t *actual_props;
- svn_boolean_t is_switched;
-
- svn_pool_clear(iterpool);
-
- SVN_ERR(svn_wc__db_is_switched(&is_wc_root, &is_switched, NULL,
- db, parent_abspath, iterpool));
-
- if (is_switched || is_wc_root)
- {
- is_wc_root = TRUE;
-
- /* If the WC root is also the root of the repository then by
- definition there are no inheritable properties to be had,
- but checking for that is just as expensive as fetching them
- anyway. */
-
- /* Grab the cached inherited properties for the WC root. */
- SVN_ERR(svn_wc__db_read_cached_iprops(&cached_iprops, db,
- parent_abspath,
- scratch_pool, iterpool));
- }
-
- /* If PARENT_ABSPATH is a true parent of LOCAL_ABSPATH, then
- LOCAL_ABSPATH can inherit properties from it. */
- if (strcmp(local_abspath, parent_abspath) != 0)
- {
- SVN_ERR(svn_wc__db_read_props(&actual_props, db, parent_abspath,
- result_pool, iterpool));
- if (actual_props)
- {
- /* If we only want PROPNAME filter out any other properties. */
- if (propname)
- filter_unwanted_props(actual_props, propname, iterpool);
-
- if (apr_hash_count(actual_props))
- {
- svn_prop_inherited_item_t *iprop_elt =
- apr_pcalloc(result_pool,
- sizeof(svn_prop_inherited_item_t));
- iprop_elt->path_or_url = apr_pstrdup(result_pool,
- parent_abspath);
- iprop_elt->prop_hash = actual_props;
- /* Build the output array in depth-first order. */
- svn_sort__array_insert(&iprop_elt, *inherited_props, 0);
- }
- }
- }
-
- /* Inheritance only goes as far as the nearest WC root. */
- if (is_wc_root)
- break;
-
- /* Keep looking for the WC root. */
- parent_abspath = svn_dirent_dirname(parent_abspath, scratch_pool);
- }
-
- if (cached_iprops)
- {
- for (i = cached_iprops->nelts - 1; i >= 0; i--)
- {
- svn_prop_inherited_item_t *cached_iprop =
- APR_ARRAY_IDX(cached_iprops, i, svn_prop_inherited_item_t *);
-
- /* An empty property hash in the iprops cache means there are no
- inherited properties. */
- if (apr_hash_count(cached_iprop->prop_hash) == 0)
- continue;
-
- if (propname)
- filter_unwanted_props(cached_iprop->prop_hash, propname,
- scratch_pool);
-
- /* If we didn't filter everything then keep this iprop. */
- if (apr_hash_count(cached_iprop->prop_hash))
- svn_sort__array_insert(&cached_iprop, *inherited_props, 0);
- }
- }
-
- svn_pool_destroy(iterpool);
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_wc__get_iprops(apr_array_header_t **inherited_props,
svn_wc_context_t *wc_ctx,
@@ -2472,9 +2320,11 @@ svn_wc__get_iprops(apr_array_header_t **
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_error_trace(svn_wc__internal_get_iprops(inherited_props, wc_ctx->db,
- local_abspath, propname,
- result_pool, scratch_pool));
+ return svn_error_trace(
+ svn_wc__db_read_inherited_props(inherited_props,
+ wc_ctx->db, local_abspath,
+ propname,
+ result_pool, scratch_pool));
}
svn_error_t *
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/props.h?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/props.h Tue Dec 4 02:26:18 2012
@@ -127,15 +127,6 @@ svn_wc__props_modified(svn_boolean_t *mo
const char *local_abspath,
apr_pool_t *scratch_pool);
-/* Internal version of svn_wc_get_pristine_props(). */
-svn_error_t *
-svn_wc__get_pristine_props(apr_hash_t **props,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
-
/* Internal version of svn_wc_prop_list2(). */
svn_error_t *
svn_wc__get_actual_props(apr_hash_t **props,
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/status.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/status.c Tue Dec 4 02:26:18 2012
@@ -1028,9 +1028,10 @@ collect_ignore_patterns(apr_array_header
FALSE, result_pool);
}
- SVN_ERR(svn_wc__internal_get_iprops(&inherited_props, db, local_abspath,
- SVN_PROP_INHERITABLE_IGNORES,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_inherited_props(&inherited_props,
+ db, local_abspath,
+ SVN_PROP_INHERITABLE_IGNORES,
+ scratch_pool, scratch_pool));
for (i = 0; i < inherited_props->nelts; i++)
{
apr_hash_index_t *hi;
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/translate.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/translate.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/translate.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/translate.c Tue Dec 4 02:26:18 2012
@@ -409,8 +409,8 @@ svn_wc__sync_flags_with_props(svn_boolea
set the file read_only just yet. That happens upon commit. */
apr_hash_t *pristine_props;
- SVN_ERR(svn_wc__get_pristine_props(&pristine_props, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props, db, local_abspath,
+ scratch_pool, scratch_pool));
if (pristine_props
&& apr_hash_get(pristine_props,
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/update_editor.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/update_editor.c Tue Dec 4 02:26:18 2012
@@ -2394,9 +2394,9 @@ close_directory(void *dir_baton,
if (db->add_existed)
{
/* This node already exists. Grab the current pristine properties. */
- SVN_ERR(svn_wc__get_pristine_props(&base_props,
- eb->db, db->local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&base_props,
+ eb->db, db->local_abspath,
+ scratch_pool, scratch_pool));
}
else if (!db->adding_dir)
{
@@ -4077,9 +4077,9 @@ close_file(void *file_baton,
if (fb->add_existed)
{
/* This node already exists. Grab the current pristine properties. */
- SVN_ERR(svn_wc__get_pristine_props(¤t_base_props,
- eb->db, fb->local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(¤t_base_props,
+ eb->db, fb->local_abspath,
+ scratch_pool, scratch_pool));
current_actual_props = local_actual_props;
}
else if (!fb->adding_file)
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql Tue Dec 4 02:26:18 2012
@@ -29,7 +29,7 @@
-- STMT_SELECT_NODE_INFO
SELECT op_depth, repos_id, repos_path, presence, kind, revision, checksum,
translated_size, changed_revision, changed_date, changed_author, depth,
- symlink_target, last_mod_time, properties, moved_here
+ symlink_target, last_mod_time, properties, moved_here, inherited_props
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
ORDER BY op_depth DESC
@@ -38,6 +38,7 @@ ORDER BY op_depth DESC
SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
checksum, translated_size, changed_revision, changed_date, changed_author,
depth, symlink_target, last_mod_time, properties, moved_here,
+ inherited_props,
/* All the columns until now must match those returned by
STMT_SELECT_NODE_INFO. The implementation of svn_wc__db_read_info()
assumes that these columns are followed by the lock information) */
@@ -219,6 +220,34 @@ DELETE FROM nodes
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
AND op_depth = 0
+-- STMT_DELETE_WORKING_OP_DEPTH
+DELETE FROM nodes
+WHERE wc_id = ?1
+ AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+ AND op_depth = ?3
+
+-- STMT_SELECT_LOCAL_RELPATH_OP_DEPTH
+SELECT local_relpath
+FROM nodes
+WHERE wc_id = ?1
+ AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+ AND op_depth = ?3
+
+-- STMT_COPY_NODE_MOVE
+INSERT INTO nodes (
+ wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
+ revision, presence, depth, kind, changed_revision, changed_date,
+ changed_author, checksum, properties, translated_size, last_mod_time,
+ symlink_target, moved_here )
+SELECT
+ wc_id, ?4 /*local_relpath */, ?5 /*op_depth*/, ?6 /* parent_relpath */,
+ repos_id,
+ repos_path, revision, presence, depth, kind, changed_revision,
+ changed_date, changed_author, checksum, properties, translated_size,
+ last_mod_time, symlink_target, 1
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
+
-- STMT_SELECT_OP_DEPTH_CHILDREN
SELECT local_relpath FROM nodes
WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3
@@ -407,10 +436,6 @@ WHERE wc_id = ?1 AND local_relpath = ?2
AND op_depth = (SELECT MAX(op_depth) FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2)
--- STMT_UPDATE_NODE_FILEINFO_OPDEPTH
-UPDATE nodes SET translated_size = ?3, last_mod_time = ?4
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?5
-
-- STMT_INSERT_ACTUAL_CONFLICT
INSERT INTO actual_node (wc_id, local_relpath, conflict_data, parent_relpath)
VALUES (?1, ?2, ?3, ?4)
@@ -478,10 +503,6 @@ BEGIN
WHERE new.changelist IS NOT NULL;
END
--- STMT_INSERT_CHANGELIST_LIST
-INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
-VALUES (?1, ?2, ?3, ?4)
-
-- STMT_FINALIZE_CHANGELIST
DROP TRIGGER trigger_changelist_list_change;
DROP TABLE changelist_list;
@@ -798,9 +819,9 @@ INSERT OR REPLACE INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
revision, presence, depth, kind, changed_revision, changed_date,
changed_author, checksum, properties, dav_cache, symlink_target,
- file_external )
+ inherited_props, file_external )
VALUES (?1, ?2, 0,
- ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16,
+ ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17,
(SELECT file_external FROM nodes
WHERE wc_id = ?1
AND local_relpath = ?2
@@ -1444,22 +1465,29 @@ SET inherited_props = ?3
WHERE (wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0)
/* Select a single path if its base node has cached inherited properties. */
--- STMT_SELECT_INODES
-SELECT local_relpath FROM nodes
+-- STMT_SELECT_IPROPS_NODE
+SELECT local_relpath, repos_path FROM nodes
WHERE wc_id = ?1
AND local_relpath = ?2
AND op_depth = 0
AND (inherited_props not null)
-/* Select all paths whose base nodes at or below a given path, which
+/* Select all paths whose base nodes are below a given path, which
have cached inherited properties. */
--- STMT_SELECT_INODES_RECURSIVE
-SELECT local_relpath FROM nodes
+-- STMT_SELECT_IPROPS_RECURSIVE
+SELECT local_relpath, repos_path FROM nodes
WHERE wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
AND op_depth = 0
AND (inherited_props not null)
+-- STMT_SELECT_IPROPS_CHILDREN
+SELECT local_relpath, repos_path FROM nodes
+WHERE wc_id = ?1
+ AND parent_relpath = ?2
+ AND op_depth = 0
+ AND (inherited_props not null)
+
/* ------------------------------------------------------------------------- */
/* Grab all the statements related to the schema. */
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc.h?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc.h Tue Dec 4 02:26:18 2012
@@ -607,15 +607,6 @@ svn_wc__internal_get_repos_relpath(const
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Internal version of svn_wc__get_iprops() */
-svn_error_t *
-svn_wc__internal_get_iprops(apr_array_header_t **inherited_props,
- svn_wc__db_t *db,
- const char *local_abspath,
- const char *propname,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
/* Upgrade the wc sqlite database given in SDB for the wc located at
WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT.
After the upgrade is complete (to as far as the automatic upgrade will
@@ -764,6 +755,16 @@ svn_wc__fetch_base_func(const char **fil
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Find duplicate targets in *EXTERNALS, a list of svn_wc_external_item2_t*
+ * elements, and store each target string in *DUPLICATE_TARGETS as const
+ * char * elements. *DUPLICATE_TARGETS will be NULL if no duplicates were
+ * found. */
+svn_error_t *
+svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets,
+ apr_array_header_t *externals,
+ apr_pool_t *pool,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c Tue Dec 4 02:26:18 2012
@@ -32,6 +32,7 @@
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_hash.h"
+#include "svn_sorts.h"
#include "svn_wc.h"
#include "svn_checksum.h"
#include "svn_pools.h"
@@ -320,6 +321,7 @@ static svn_error_t *
db_read_pristine_props(apr_hash_t **props,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ svn_boolean_t deleted_ok,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -381,7 +383,18 @@ wclock_owns_lock(svn_boolean_t *own_lock
svn_boolean_t exact,
apr_pool_t *scratch_pool);
+/* Baton for db_is_switched */
+struct db_is_switched_baton_t
+{
+ svn_boolean_t *is_switched;
+ svn_kind_t *kind;
+};
+static svn_error_t *
+db_is_switched(void *baton,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool);
/* Return the absolute path, in local path style, of LOCAL_RELPATH
in WCROOT. */
@@ -3640,7 +3653,7 @@ cross_db_copy(svn_wc__db_wcroot_t *src_w
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
src_wcroot, src_relpath, scratch_pool, scratch_pool));
- SVN_ERR(db_read_pristine_props(&props, src_wcroot, src_relpath,
+ SVN_ERR(db_read_pristine_props(&props, src_wcroot, src_relpath, FALSE,
scratch_pool, scratch_pool));
blank_iwb(&iwb);
@@ -5089,7 +5102,7 @@ set_props_txn(void *baton,
/* Check if the props are modified. If no changes, then wipe out the
ACTUAL props. PRISTINE_PROPS==NULL means that any
ACTUAL props are okay as provided, so go ahead and set them. */
- SVN_ERR(db_read_pristine_props(&pristine_props, wcroot, local_relpath,
+ SVN_ERR(db_read_pristine_props(&pristine_props, wcroot, local_relpath, FALSE,
scratch_pool, scratch_pool));
if (spb->props && pristine_props)
{
@@ -7667,7 +7680,7 @@ read_info(svn_wc__db_status_t *status,
if (op_depth != 0)
*lock = NULL;
else
- *lock = lock_from_columns(stmt_info, 16, 17, 18, 19, result_pool);
+ *lock = lock_from_columns(stmt_info, 17, 18, 19, 20, result_pool);
}
if (have_work)
@@ -8829,7 +8842,7 @@ db_read_props(void *baton,
return SVN_NO_ERROR;
/* No local changes. Return the pristine props for this node. */
- SVN_ERR(db_read_pristine_props(&rpb->props, wcroot, local_relpath,
+ SVN_ERR(db_read_pristine_props(&rpb->props, wcroot, local_relpath, FALSE,
rpb->result_pool, scratch_pool));
if (rpb->props == NULL)
{
@@ -8877,6 +8890,7 @@ static svn_error_t *
db_read_pristine_props(apr_hash_t **props,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
+ svn_boolean_t deleted_ok,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -8904,9 +8918,8 @@ db_read_pristine_props(apr_hash_t **prop
presence = svn_sqlite__column_token(stmt, 1, presence_map);
/* For "base-deleted", it is obvious the pristine props are located
- in the BASE table. Fall through to fetch them.
- ### BH: Is this really the behavior we want here? */
- if (presence == svn_wc__db_status_base_deleted)
+ below the current node. Fetch the NODE from the next record. */
+ if (presence == svn_wc__db_status_base_deleted && deleted_ok)
{
SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -8932,8 +8945,13 @@ db_read_pristine_props(apr_hash_t **prop
return SVN_NO_ERROR;
}
- *props = NULL;
- return svn_error_trace(svn_sqlite__reset(stmt));
+ return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
+ svn_sqlite__reset(stmt),
+ _("The node '%s' has a status that"
+ " has no properties."),
+ path_for_error_message(wcroot,
+ local_relpath,
+ scratch_pool));
}
@@ -8953,7 +8971,7 @@ svn_wc__db_read_pristine_props(apr_hash_
local_abspath, scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- SVN_ERR(db_read_pristine_props(props, wcroot, local_relpath,
+ SVN_ERR(db_read_pristine_props(props, wcroot, local_relpath, TRUE,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -9018,6 +9036,45 @@ svn_wc__db_prop_retrieve_recursive(apr_h
return svn_error_trace(svn_sqlite__reset(stmt));
}
+/* Baton for db_read_cached_iprops */
+struct read_cached_iprops_baton_t
+{
+ apr_array_header_t *iprops;
+ apr_pool_t *result_pool;
+};
+
+/* Implements svn_wc__db_txn_callback_t for svn_wc__db_read_cached_iprops */
+static svn_error_t *
+db_read_cached_iprops(void *baton,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ struct read_cached_iprops_baton_t *rib = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_IPROPS));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (!have_row)
+ {
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
+ svn_sqlite__reset(stmt),
+ _("The node '%s' was not found."),
+ path_for_error_message(wcroot, local_relpath,
+ scratch_pool));
+ }
+
+ SVN_ERR(svn_sqlite__column_iprops(&rib->iprops, stmt, 0,
+ rib->result_pool, scratch_pool));
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_wc__db_read_cached_iprops(apr_array_header_t **iprops,
svn_wc__db_t *db,
@@ -9027,8 +9084,7 @@ svn_wc__db_read_cached_iprops(apr_array_
{
svn_wc__db_wcroot_t *wcroot;
const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
+ struct read_cached_iprops_baton_t rcib;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -9036,61 +9092,261 @@ svn_wc__db_read_cached_iprops(apr_array_
db, local_abspath,
scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_IPROPS));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (!have_row)
+ rcib.result_pool = result_pool;
+
+ /* Don't use with_txn yet, as we perform just a single transaction */
+ SVN_ERR(db_read_cached_iprops(&rcib, wcroot, local_relpath, scratch_pool));
+
+ if (rcib.iprops)
+ *iprops = rcib.iprops;
+ else
{
- /* No cached iprops. */
- *iprops = NULL;
+ *iprops = apr_array_make(result_pool, 0,
+ sizeof(svn_prop_inherited_item_t *));
}
- else
+
+ return SVN_NO_ERROR;
+}
+
+/* Remove all prop name value pairs from PROP_HASH where the property
+ name is not PROPNAME. */
+static void
+filter_unwanted_props(apr_hash_t *prop_hash,
+ const char * propname,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(scratch_pool, prop_hash);
+ hi;
+ hi = apr_hash_next(hi))
{
- SVN_ERR(svn_sqlite__column_iprops(iprops, stmt, 0, result_pool,
- scratch_pool));
- if (!*iprops)
- *iprops = apr_array_make(result_pool, 0,
- sizeof(svn_prop_inherited_item_t *));
+ const char *ipropname = svn__apr_hash_index_key(hi);
- }
+ if (strcmp(ipropname, propname) != 0)
+ apr_hash_set(prop_hash, ipropname, APR_HASH_KEY_STRING, NULL);
+ }
+ return;
+}
- SVN_ERR(svn_sqlite__reset(stmt));
+/* Baton for db_read_inherited_props */
+struct read_inherited_props_baton_t
+{
+ apr_array_header_t *iprops;
+ const char *propname;
+ apr_pool_t *result_pool;
+};
+
+/* Implements svn_wc__db_txn_callback_t for svn_wc__db_read_inherited_props */
+static svn_error_t *
+db_read_inherited_props(void *baton,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ struct read_inherited_props_baton_t *ripb = baton;
+ int i;
+ apr_array_header_t *cached_iprops = NULL;
+ const char *parent_relpath = local_relpath;
+ svn_boolean_t is_wc_root = FALSE;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ apr_pool_t *result_pool = ripb->result_pool;
+
+ ripb->iprops = apr_array_make(ripb->result_pool, 1,
+ sizeof(svn_prop_inherited_item_t *));
+
+ /* Walk up to the root of the WC looking for inherited properties. When we
+ reach the WC root also check for cached inherited properties. */
+ while (TRUE)
+ {
+ apr_hash_t *actual_props;
+ svn_boolean_t is_switched;
+ struct db_is_switched_baton_t swb;
+
+ svn_pool_clear(iterpool);
+
+ swb.is_switched = &is_switched;
+ swb.kind = NULL;
+
+ if (*parent_relpath == '\0')
+ {
+ is_switched = FALSE;
+ is_wc_root = TRUE;
+ }
+ else
+ SVN_ERR(db_is_switched(&swb, wcroot, parent_relpath, scratch_pool));
+
+ if (is_switched || is_wc_root)
+ {
+ struct read_cached_iprops_baton_t rib;
+ is_wc_root = TRUE;
+
+ rib.result_pool = scratch_pool;
+
+ /* If the WC root is also the root of the repository then by
+ definition there are no inheritable properties to be had,
+ but checking for that is just as expensive as fetching them
+ anyway. */
+
+ /* Grab the cached inherited properties for the WC root. */
+ SVN_ERR(db_read_cached_iprops(&rib, wcroot, parent_relpath,
+ iterpool));
+
+ cached_iprops = rib.iprops;
+ }
+
+ /* If PARENT_ABSPATH is a true parent of LOCAL_ABSPATH, then
+ LOCAL_ABSPATH can inherit properties from it. */
+ if (strcmp(local_relpath, parent_relpath) != 0)
+ {
+ struct db_read_props_baton_t rpb;
+ rpb.result_pool = result_pool;
+
+ SVN_ERR(db_read_props(&rpb, wcroot, parent_relpath, iterpool));
+
+ actual_props = rpb.props;
+
+ if (actual_props)
+ {
+ /* If we only want PROPNAME filter out any other properties. */
+ if (ripb->propname)
+ filter_unwanted_props(actual_props, ripb->propname, iterpool);
+
+ if (apr_hash_count(actual_props))
+ {
+ svn_prop_inherited_item_t *iprop_elt =
+ apr_pcalloc(ripb->result_pool,
+ sizeof(svn_prop_inherited_item_t));
+ iprop_elt->path_or_url = svn_dirent_join(wcroot->abspath,
+ parent_relpath,
+ result_pool);
+
+ iprop_elt->prop_hash = actual_props;
+ /* Build the output array in depth-first order. */
+ svn_sort__array_insert(&iprop_elt, ripb->iprops, 0);
+ }
+ }
+ }
+
+ /* Inheritance only goes as far as the nearest WC root. */
+ if (is_wc_root)
+ break;
+
+ /* Keep looking for the WC root. */
+ parent_relpath = svn_relpath_dirname(parent_relpath, scratch_pool);
+ }
+
+ if (cached_iprops)
+ {
+ for (i = cached_iprops->nelts - 1; i >= 0; i--)
+ {
+ svn_prop_inherited_item_t *cached_iprop =
+ APR_ARRAY_IDX(cached_iprops, i, svn_prop_inherited_item_t *);
+
+ /* An empty property hash in the iprops cache means there are no
+ inherited properties. */
+ if (apr_hash_count(cached_iprop->prop_hash) == 0)
+ continue;
+ if (ripb->propname)
+ filter_unwanted_props(cached_iprop->prop_hash, ripb->propname,
+ scratch_pool);
+
+ /* If we didn't filter everything then keep this iprop. */
+ if (apr_hash_count(cached_iprop->prop_hash))
+ svn_sort__array_insert(&cached_iprop, ripb->iprops, 0);
+ }
+ }
+
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-/* Recursive body of svn_wc__db_get_children_with_cached_iprops. */
-static svn_error_t *
-get_children_with_cached_iprops(apr_hash_t *iprop_paths,
- svn_depth_t depth,
- const char *local_abspath,
+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)
{
svn_wc__db_wcroot_t *wcroot;
const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
+ struct read_inherited_props_baton_t ripb;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
- local_abspath, scratch_pool,
- scratch_pool));
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- if (depth == svn_depth_empty
- || depth == svn_depth_files
- || depth == svn_depth_immediates)
+
+ ripb.iprops = NULL;
+ ripb.propname = propname;
+ ripb.result_pool = result_pool;
+
+ SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_read_inherited_props,
+ &ripb, scratch_pool));
+
+ *iprops = ripb.iprops;
+ return SVN_NO_ERROR;
+}
+
+/* Baton for get_children_with_cached_iprops */
+struct get_children_with_cached_baton_t
+{
+ svn_depth_t depth;
+ apr_hash_t *iprop_paths;
+ apr_pool_t *result_pool;
+};
+
+/* Implements svn_wc__db_txn_callback_t for
+ svn_wc__db_get_children_with_cached_iprops. */
+static svn_error_t *
+get_children_with_cached_iprops(void *baton,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ struct get_children_with_cached_baton_t *cwcb = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ apr_hash_t *iprop_paths = cwcb->iprop_paths;
+ apr_pool_t *result_pool = cwcb->result_pool;
+
+ /* First check if LOCAL_RELPATH itself has iprops */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_IPROPS_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (have_row)
+ {
+ const char *relpath_with_cache = svn_sqlite__column_text(stmt, 0,
+ NULL);
+ const char *abspath_with_cache = svn_dirent_join(wcroot->abspath,
+ relpath_with_cache,
+ result_pool);
+ apr_hash_set(iprop_paths, abspath_with_cache, APR_HASH_KEY_STRING,
+ svn_sqlite__column_text(stmt, 1, result_pool));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (cwcb->depth == svn_depth_empty)
+ return SVN_NO_ERROR;
+
+ /* Now fetch information for children or all descendants */
+ if (cwcb->depth == svn_depth_files
+ || cwcb->depth == svn_depth_immediates)
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_INODES));
+ STMT_SELECT_IPROPS_CHILDREN));
}
else /* Default to svn_depth_infinity. */
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_INODES_RECURSIVE));
+ STMT_SELECT_IPROPS_RECURSIVE));
}
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
@@ -9104,46 +9360,50 @@ get_children_with_cached_iprops(apr_hash
relpath_with_cache,
result_pool);
apr_hash_set(iprop_paths, abspath_with_cache, APR_HASH_KEY_STRING,
- abspath_with_cache);
+ svn_sqlite__column_text(stmt, 1, result_pool));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
SVN_ERR(svn_sqlite__reset(stmt));
- if (depth == svn_depth_files || depth == svn_depth_immediates)
+ /* For depth files we should filter non files */
+ if (cwcb->depth == svn_depth_files)
{
- const apr_array_header_t *rel_children;
- int i;
+ apr_hash_index_t *hi;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- SVN_ERR(svn_wc__db_read_children_of_working_node(&rel_children,
- db, local_abspath,
- scratch_pool,
- scratch_pool));
- for (i = 0; i < rel_children->nelts; i++)
+ for (hi = apr_hash_first(scratch_pool, iprop_paths);
+ hi;
+ hi = apr_hash_next(hi))
{
- const char *child_abspath;
+ const char *child_abspath = svn__apr_hash_index_key(hi);
+ const char *child_relpath;
+ svn_kind_t child_kind;
svn_pool_clear(iterpool);
- child_abspath = svn_dirent_join(
- local_abspath, APR_ARRAY_IDX(rel_children, i, const char *),
- iterpool);
- if (depth == svn_depth_files)
- {
- svn_kind_t child_kind;
+ child_relpath = svn_dirent_is_child(local_relpath, child_abspath,
+ NULL);
- SVN_ERR(svn_wc__db_read_kind(&child_kind, db, child_abspath,
- FALSE, FALSE, iterpool));
- if (child_kind != svn_kind_file)
- continue;
+ if (! child_relpath)
+ {
+ continue; /* local_relpath itself */
}
- SVN_ERR(get_children_with_cached_iprops(iprop_paths,
- svn_depth_empty,
- child_abspath, db,
- result_pool,
- iterpool));
+ 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_relpath,
+ scratch_pool,
+ scratch_pool));
+
+ /* Filter if not a file */
+ if (child_kind != svn_kind_file)
+ {
+ apr_hash_set(iprop_paths, child_abspath, APR_HASH_KEY_STRING,
+ NULL);
+ }
}
svn_pool_destroy(iterpool);
@@ -9160,10 +9420,26 @@ svn_wc__db_get_children_with_cached_ipro
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- *iprop_paths = apr_hash_make(result_pool);
- SVN_ERR(get_children_with_cached_iprops(*iprop_paths, depth,
- local_abspath, db, result_pool,
- scratch_pool));
+ svn_wc__db_wcroot_t *wcroot;
+ const char *local_relpath;
+ struct get_children_with_cached_baton_t cwcb;
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+ local_abspath, scratch_pool,
+ scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ cwcb.iprop_paths = apr_hash_make(result_pool);
+ cwcb.depth = depth;
+ cwcb.result_pool = result_pool;
+
+ SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath,
+ get_children_with_cached_iprops, &cwcb,
+ scratch_pool));
+
+ *iprop_paths = cwcb.iprop_paths;
return SVN_NO_ERROR;
}
@@ -9669,6 +9945,7 @@ commit_node(void *baton,
svn_sqlite__stmt_t *stmt_act;
svn_boolean_t have_act;
svn_string_t prop_blob = { 0 };
+ svn_string_t inherited_prop_blob = { 0 };
const char *changelist = NULL;
const char *parent_relpath;
svn_wc__db_status_t new_presence;
@@ -9738,6 +10015,10 @@ commit_node(void *baton,
prop_blob.data = svn_sqlite__column_blob(stmt_info, 14, &prop_blob.len,
scratch_pool);
+ inherited_prop_blob.data = svn_sqlite__column_blob(stmt_info, 16,
+ &inherited_prop_blob.len,
+ scratch_pool);
+
if (cb->keep_changelist && have_act)
changelist = svn_sqlite__column_text(stmt_act, 0, scratch_pool);
@@ -9824,6 +10105,11 @@ commit_node(void *baton,
scratch_pool));
SVN_ERR(svn_sqlite__bind_properties(stmt, 15, cb->new_dav_cache,
scratch_pool));
+ if (inherited_prop_blob.data != NULL)
+ {
+ SVN_ERR(svn_sqlite__bind_blob(stmt, 17, inherited_prop_blob.data,
+ inherited_prop_blob.len));
+ }
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -12458,13 +12744,6 @@ svn_wc__db_is_wcroot(svn_boolean_t *is_r
return SVN_NO_ERROR;
}
-/* Baton for db_is_switched */
-struct db_is_switched_baton_t
-{
- svn_boolean_t *is_switched;
- svn_kind_t *kind;
-};
-
/* This implements svn_wc__db_txn_callback_t for svn_wc_db__is_switched */
static svn_error_t *
db_is_switched(void *baton,
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h Tue Dec 4 02:26:18 2012
@@ -2094,6 +2094,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
@@ -2116,9 +2136,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,
@@ -3225,8 +3247,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,
Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c Tue Dec 4 02:26:18 2012
@@ -53,14 +53,17 @@
/*
* 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;
svn_wc_conflict_version_t *old_version;
svn_wc_conflict_version_t *new_version;
svn_wc_notify_func2_t notify_func;
@@ -410,6 +413,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 +439,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 +464,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)
{
@@ -650,7 +672,93 @@ update_moved_away_subtree(svn_editor_t *
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,
+ 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 src_op_depth;
+ int dst_op_depth = relpath_depth(dst_relpath);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_NODE_INFO));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, src_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ 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(src_relpath,
+ scratch_pool));
+
+ /* Delete entire subtree at one op-depth. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_DELETE_WORKING_OP_DEPTH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ dst_relpath, dst_op_depth));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ /* Copy 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));
+
+ /* TODO: extend/retract any base-deleted layers to account for
+ added/removed nodes in the replaced layer. */
+
+ 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,
@@ -680,17 +788,9 @@ 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,
dst_relpath, old_version->peg_rev,
@@ -702,18 +802,20 @@ drive_tree_conflict_editor(svn_editor_t
SVN_ERR(svn_editor_complete(tc_editor));
+ SVN_ERR(replace_moved_layer(src_relpath, dst_relpath, 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;
@@ -737,16 +839,15 @@ update_moved_away_conflict_victim(void *
/* 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;
@@ -782,8 +883,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 +895,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 +907,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/ev2-export/subversion/mod_dav_svn/reports/inherited-props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/mod_dav_svn/reports/inherited-props.c?rev=1416748&r1=1416747&r2=1416748&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/mod_dav_svn/reports/inherited-props.c (original)
+++ subversion/branches/ev2-export/subversion/mod_dav_svn/reports/inherited-props.c Tue Dec 4 02:26:18 2012
@@ -113,7 +113,7 @@ dav_svn__get_inherited_props_report(cons
"couldn't retrieve revision root",
resource->pool);
- serr = svn_repos_fs_get_inherited_props(&inherited_props, root, path,
+ serr = svn_repos_fs_get_inherited_props(&inherited_props, root, path, NULL,
dav_svn__authz_read_func(&arb),
&arb, resource->pool, iterpool);
if (serr)