You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/07/23 21:37:24 UTC
svn commit: r967221 [4/7] - in /subversion/branches/atomic-revprop: ./
build/generator/ notes/ notes/tree-conflicts/
subversion/bindings/javahl/tests/org/apache/subversion/javahl/
subversion/bindings/javahl/tests/org/tigris/subversion/javahl/ subversio...
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/log.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/log.h?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/log.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/log.h Fri Jul 23 19:37:19 2010
@@ -47,22 +47,6 @@ extern "C" {
ADM_ABSPATH (or equal to it, where that makes sense).
*/
-
-/* Set *WORK_ITEM to a work queue instruction to generate a translated
- file from SRC_ABSPATH to DST_ABSPATH with translation settings from
- VERSIONED_ABSPATH.
-
- ADM_ABSPATH is described above.
-*/
-svn_error_t *
-svn_wc__loggy_translated_file(svn_skel_t **work_item,
- svn_wc__db_t *db,
- const char *adm_abspath,
- const char *dst_abspath,
- const char *src_abspath,
- const char *versioned_abspath,
- apr_pool_t *result_pool);
-
/* Set *WORK_ITEM to a work queue instruction to delete the entry
associated with LOCAL_ABSPATH from the entries file.
@@ -81,40 +65,6 @@ svn_wc__loggy_delete_entry(svn_skel_t **
svn_wc__db_kind_t kind,
apr_pool_t *result_pool);
-/* Set *WORK_ITEM to a work queue instruction to move the file SRC_ABSPATH
- to DST_ABSPATH.
-
- The file SRC_ABSPATH must exist. The test for existence is made now, not
- at log run time.
-
- Set *DST_MODIFIED (if DST_MODIFIED isn't NULL) to indicate whether the
- destination path will have been modified after running the log: if either
- the move or the remove will have been carried out.
-
- ADM_ABSPATH is described above.
-*/
-svn_error_t *
-svn_wc__loggy_move(svn_skel_t **work_item,
- svn_wc__db_t *db,
- const char *adm_abspath,
- const char *src_abspath,
- const char *dst_abspath,
- apr_pool_t *result_pool);
-
-
-/* Set *WORK_ITEM to a work queue instruction to set the timestamp of
- LOCAL_ABSPATH to the time TIMESTR.
-
- ADM_ABSPATH is described above.
-*/
-svn_error_t *
-svn_wc__loggy_set_timestamp(svn_skel_t **work_item,
- svn_wc__db_t *db,
- const char *adm_abspath,
- const char *local_abspath,
- const char *timestr,
- apr_pool_t *result_pool);
-
/* Set *WORK_ITEM to a work queue instruction to
### ...
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/merge.c Fri Jul 23 19:37:19 2010
@@ -134,10 +134,16 @@ detranslate_wc_file(const char **detrans
const char *eol;
apr_hash_t *keywords;
svn_boolean_t special;
+ svn_wc__db_kind_t kind;
+
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, target_abspath, TRUE, scratch_pool));
/* Decide if the merge target currently is a text or binary file. */
- SVN_ERR(svn_wc__marked_as_binary(&is_binary, target_abspath, db,
- scratch_pool));
+ if (kind == svn_wc__db_kind_file)
+ SVN_ERR(svn_wc__marked_as_binary(&is_binary, target_abspath, db,
+ scratch_pool));
+ else
+ is_binary = FALSE;
/* See if we need to do a straight copy:
- old and new mime-types are binary, or
@@ -159,18 +165,38 @@ detranslate_wc_file(const char **detrans
{
/* Old props indicate texty, new props indicate binary:
detranslate keywords and old eol-style */
- SVN_ERR(svn_wc__get_keywords(&keywords, db, target_abspath, NULL,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_special(&special, db, target_abspath, scratch_pool));
- SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, target_abspath,
- scratch_pool, scratch_pool));
+ if (kind == svn_wc__db_kind_file)
+ SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+ &keywords,
+ &special,
+ db, target_abspath,
+ scratch_pool, scratch_pool));
+ else
+ {
+ special = FALSE;
+ keywords = NULL;
+ eol = NULL;
+ style = svn_subst_eol_style_none;
+ }
}
else
{
/* New props indicate texty, regardless of old props */
/* In case the file used to be special, detranslate specially */
- SVN_ERR(svn_wc__get_special(&special, db, target_abspath, scratch_pool));
+ if (kind == svn_wc__db_kind_file)
+ SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+ &keywords,
+ &special,
+ db, target_abspath,
+ scratch_pool, scratch_pool));
+ else
+ {
+ special = FALSE;
+ keywords = NULL;
+ eol = NULL;
+ style = svn_subst_eol_style_none;
+ }
if (special)
{
@@ -187,8 +213,9 @@ detranslate_wc_file(const char **detrans
svn_subst_eol_style_from_value(&style, &eol, prop->value->data);
}
else if (!is_binary)
- SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, target_abspath,
- scratch_pool, scratch_pool));
+ {
+ /* Already fetched */
+ }
else
{
eol = NULL;
@@ -197,10 +224,7 @@ detranslate_wc_file(const char **detrans
/* In case there were keywords, detranslate with keywords
(iff we were texty) */
- if (!is_binary)
- SVN_ERR(svn_wc__get_keywords(&keywords, db, target_abspath, NULL,
- scratch_pool, scratch_pool));
- else
+ if (is_binary)
keywords = NULL;
}
}
@@ -439,12 +463,10 @@ save_merge_result(svn_skel_t **work_item
".edited",
svn_io_file_del_none,
scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__loggy_translated_file(work_item,
- db, dir_abspath,
- edited_copy_abspath,
- source,
- versioned_abspath,
- result_pool));
+ SVN_ERR(svn_wc__wq_build_file_copy_translated(work_item,
+ db, versioned_abspath,
+ source, edited_copy_abspath,
+ result_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -621,6 +643,9 @@ eval_conflict_func_result(svn_skel_t **w
The translation to working-copy form will be done according to the
versioned properties of TARGET_ABSPATH that are current when the work
queue items are executed.
+
+ If target_abspath is not versioned use detranslated_target_abspath
+ as the target file.
*/
static svn_error_t *
preserve_pre_merge_files(svn_skel_t **work_items,
@@ -634,6 +659,7 @@ preserve_pre_merge_files(svn_skel_t **wo
const char *left_label,
const char *right_label,
const char *target_label,
+ const char *detranslated_target_abspath,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
@@ -643,6 +669,7 @@ preserve_pre_merge_files(svn_skel_t **wo
const char *dir_abspath, *target_name;
const char *temp_dir;
svn_skel_t *work_item;
+ svn_error_t *err;
*work_items = NULL;
@@ -705,26 +732,42 @@ preserve_pre_merge_files(svn_skel_t **wo
/* Create LEFT and RIGHT backup files, in expanded form.
We use TARGET_ABSPATH's current properties to do the translation. */
/* Derive the basenames of the 3 backup files. */
- SVN_ERR(svn_wc__loggy_translated_file(&work_item, db, dir_abspath,
- *left_copy, tmp_left,
- target_abspath, result_pool));
+ SVN_ERR(svn_wc__wq_build_file_copy_translated(&work_item,
+ db, target_abspath,
+ tmp_left, *left_copy,
+ result_pool, scratch_pool));
*work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
- SVN_ERR(svn_wc__loggy_translated_file(&work_item, db, dir_abspath,
- *right_copy, tmp_right,
- target_abspath, result_pool));
+ SVN_ERR(svn_wc__wq_build_file_copy_translated(&work_item,
+ db, target_abspath,
+ tmp_right, *right_copy,
+ result_pool, scratch_pool));
*work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
/* Back up TARGET_ABSPATH through detranslation/retranslation:
the new translation properties may not match the current ones */
- SVN_ERR(svn_wc__internal_translated_file(
+ err = svn_wc__internal_translated_file(
&detranslated_target_copy, target_abspath, db, target_abspath,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
cancel_func, cancel_baton,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__loggy_translated_file(&work_item, db, dir_abspath,
- *target_copy, detranslated_target_copy,
- target_abspath, result_pool));
+ scratch_pool, scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+
+ /* We are merging to a not versioned file, so we have handle
+ this without translation */
+ detranslated_target_copy = detranslated_target_abspath;
+ }
+ else
+ SVN_ERR(err);
+
+ SVN_ERR(svn_wc__wq_build_file_copy_translated(&work_item,
+ db, target_abspath,
+ detranslated_target_copy,
+ *target_copy,
+ result_pool, scratch_pool));
*work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
return SVN_NO_ERROR;
@@ -980,6 +1023,7 @@ merge_text_file(svn_skel_t **work_items,
db,
left_abspath, right_abspath, target_abspath,
left_label, right_label, target_label,
+ detranslated_target_abspath,
cancel_func, cancel_baton,
result_pool, scratch_pool));
*work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
@@ -1011,7 +1055,9 @@ merge_text_file(svn_skel_t **work_items,
target file. This is so we don't try to follow symlinks,
but the same treatment is probably also appropriate for
whatever special file types we may invent in the future. */
- SVN_ERR(svn_wc__get_special(&special, db, target_abspath, pool));
+ SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
+ &special, db, target_abspath,
+ pool, pool));
SVN_ERR(svn_io_files_contents_same_p(&same, result_target,
(special ?
detranslated_target_abspath :
@@ -1193,11 +1239,10 @@ merge_binary_file(svn_skel_t **work_item
target_label,
svn_io_file_del_none,
pool, pool));
- SVN_ERR(svn_wc__loggy_move(work_items, db,
- merge_dirpath,
- detranslated_target_abspath,
- mine_copy,
- result_pool));
+ SVN_ERR(svn_wc__wq_build_file_move(work_items, db,
+ detranslated_target_abspath,
+ mine_copy,
+ pool, result_pool));
mine_copy = svn_dirent_is_child(merge_dirpath,
mine_copy, pool);
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/props.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/props.c Fri Jul 23 19:37:19 2010
@@ -2197,22 +2197,12 @@ svn_wc__internal_propget(const svn_strin
{
apr_hash_t *prophash = NULL;
enum svn_prop_kind kind = svn_property_kind(NULL, name);
- svn_wc__db_kind_t wc_kind;
svn_boolean_t hidden;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(kind != svn_prop_entry_kind);
- SVN_ERR(svn_wc__db_read_kind(&wc_kind, db, local_abspath, TRUE, scratch_pool));
-
- if (wc_kind == svn_wc__db_kind_unknown)
- {
- /* The node is not present, or not really "here". Therefore, the
- property is not present. */
- *value = NULL;
- return SVN_NO_ERROR;
- }
-
+ /* 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)
{
@@ -2235,14 +2225,14 @@ svn_wc__internal_propget(const svn_strin
svn_error_clear(err);
return SVN_NO_ERROR;
}
- SVN_ERR_W(err, _("Failed to load properties from disk"));
+ SVN_ERR_W(err, _("Failed to load properties"));
}
else
{
/* regular prop */
SVN_ERR_W(svn_wc__get_actual_props(&prophash, db, local_abspath,
result_pool, scratch_pool),
- _("Failed to load properties from disk"));
+ _("Failed to load properties"));
}
if (prophash)
@@ -2510,12 +2500,19 @@ svn_wc__internal_propset(svn_wc__db_t *d
APR_HASH_KEY_STRING);
apr_hash_t *old_keywords, *new_keywords;
- SVN_ERR(svn_wc__get_keywords(&old_keywords, db, local_abspath,
- old_value ? old_value->data : "",
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_keywords(&new_keywords, db, local_abspath,
- value ? value->data : "",
- scratch_pool, scratch_pool));
+ if (old_value)
+ SVN_ERR(svn_wc__expand_keywords(&old_keywords,
+ db, local_abspath, old_value->data,
+ scratch_pool, scratch_pool));
+ else
+ old_keywords = apr_hash_make(scratch_pool);
+
+ if (value)
+ SVN_ERR(svn_wc__expand_keywords(&new_keywords,
+ db, local_abspath, value->data,
+ scratch_pool, scratch_pool));
+ else
+ new_keywords = apr_hash_make(scratch_pool);
if (svn_subst_keywords_differ2(old_keywords, new_keywords, FALSE,
scratch_pool))
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/questions.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/questions.c Fri Jul 23 19:37:19 2010
@@ -114,13 +114,11 @@ compare_and_verify(svn_boolean_t *modifi
SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_file_abspath));
- SVN_ERR(svn_wc__get_eol_style(&eol_style, &eol_str, db,
- versioned_file_abspath, scratch_pool,
- scratch_pool));
- SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_file_abspath, NULL,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_special(&special, db, versioned_file_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__get_translate_info(&eol_style, &eol_str,
+ &keywords,
+ &special,
+ db, versioned_file_abspath,
+ scratch_pool, scratch_pool));
need_translation = svn_subst_translation_required(eol_style, eol_str,
keywords, special, TRUE);
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/status.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/status.c Fri Jul 23 19:37:19 2010
@@ -478,8 +478,10 @@ assemble_status(svn_wc_status3_t **statu
#ifdef HAVE_SYMLINK
if (has_props)
- SVN_ERR(svn_wc__get_special(&wc_special, db, local_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
+ &wc_special,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
else
wc_special = FALSE;
#endif /* HAVE_SYMLINK */
@@ -1128,6 +1130,7 @@ get_dir_status(const struct walk_status_
svn_wc__db_status_t dir_status;
svn_depth_t dir_depth;
apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
+ svn_error_t *err;
/* See if someone wants to cancel this operation. */
if (cancel_func)
@@ -1148,7 +1151,18 @@ get_dir_status(const struct walk_status_
SVN_ERR(svn_hash_from_cstring_keys(&nodes, child_nodes, subpool));
}
- SVN_ERR(svn_io_get_dirents3(&dirents, local_abspath, FALSE, subpool, subpool));
+ err = svn_io_get_dirents3(&dirents, local_abspath, FALSE, subpool, subpool);
+#ifdef SVN_WC__SINGLE_DB
+ if (err
+ && (APR_STATUS_IS_ENOENT(err->apr_err)
+ || APR_STATUS_IS_ENODIR(err->apr_err)))
+ {
+ svn_error_clear(err);
+ dirents = apr_hash_make(subpool);
+ }
+ else
+#endif
+ SVN_ERR(err);
SVN_ERR(svn_wc__db_read_info(&dir_status, NULL, NULL, &dir_repos_relpath,
&dir_repos_root_url, NULL, NULL, NULL, NULL,
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.c Fri Jul 23 19:37:19 2010
@@ -83,7 +83,11 @@ svn_wc__internal_translated_stream(svn_s
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_abspath));
- SVN_ERR(svn_wc__get_special(&special, db, versioned_abspath, scratch_pool));
+ SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+ &keywords,
+ &special,
+ db, versioned_abspath,
+ scratch_pool, scratch_pool));
if (special)
{
@@ -95,11 +99,6 @@ svn_wc__internal_translated_stream(svn_s
scratch_pool);
}
- SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, versioned_abspath,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_abspath, NULL,
- scratch_pool, scratch_pool));
-
if (to_nf)
SVN_ERR(svn_stream_open_readonly(stream, local_abspath, result_pool,
scratch_pool));
@@ -170,11 +169,11 @@ svn_wc__internal_translated_file(const c
SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_abspath));
- SVN_ERR(svn_wc__get_eol_style(&style, &eol, db, versioned_abspath,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_keywords(&keywords, db, versioned_abspath, NULL,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_wc__get_special(&special, db, versioned_abspath, scratch_pool));
+ SVN_ERR(svn_wc__get_translate_info(&style, &eol,
+ &keywords,
+ &special,
+ db, versioned_abspath,
+ scratch_pool, scratch_pool));
if (! svn_subst_translation_required(style, eol, keywords, special, TRUE)
&& (! (flags & SVN_WC_TRANSLATE_FORCE_COPY)))
@@ -240,31 +239,6 @@ svn_wc__internal_translated_file(const c
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_wc__get_eol_style(svn_subst_eol_style_t *style,
- const char **eol,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- const svn_string_t *propval;
-
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
- /* Get the property value. */
- SVN_ERR(svn_wc__internal_propget(&propval, db, local_abspath,
- SVN_PROP_EOL_STYLE, result_pool,
- scratch_pool));
-
- /* Convert it. */
- svn_subst_eol_style_from_value(style, eol, propval ? propval->data : NULL);
-
- return SVN_NO_ERROR;
-}
-
-
void
svn_wc__eol_value_from_string(const char **value, const char *eol)
{
@@ -280,56 +254,82 @@ svn_wc__eol_value_from_string(const char
*value = NULL;
}
-
svn_error_t *
-svn_wc__get_keywords(apr_hash_t **keywords,
- svn_wc__db_t *db,
- const char *local_abspath,
- const char *force_list,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_wc__get_translate_info(svn_subst_eol_style_t *style,
+ const char **eol,
+ apr_hash_t **keywords,
+ svn_boolean_t *special,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- const char *list;
- svn_revnum_t changed_rev;
- apr_time_t changed_date;
- const char *changed_author;
- const char *url;
-
+ apr_hash_t *props;
+ svn_string_t *propval;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- /* Choose a property list to parse: either the one that came into
- this function, or the one attached to PATH. */
- if (force_list == NULL)
- {
- const svn_string_t *propval;
-
- SVN_ERR(svn_wc__internal_propget(&propval, db, local_abspath,
- SVN_PROP_KEYWORDS, scratch_pool,
- scratch_pool));
+ SVN_ERR(svn_wc__get_actual_props(&props, db, local_abspath,
+ scratch_pool, scratch_pool));
- /* The easy answer. */
- if (propval == NULL)
- {
- *keywords = NULL;
- return SVN_NO_ERROR;
- }
+ if (eol)
+ {
+ propval = props ? apr_hash_get(props, SVN_PROP_EOL_STYLE,
+ APR_HASH_KEY_STRING) : NULL;
- list = propval->data;
+ svn_subst_eol_style_from_value(style, eol, propval ? propval->data : NULL);
}
- else
- list = force_list;
+
+ if (keywords)
+ {
+ propval = props ? apr_hash_get(props, SVN_PROP_KEYWORDS,
+ APR_HASH_KEY_STRING) : NULL;
+
+ if (!propval || propval->len == 0)
+ *keywords = NULL;
+ else
+ SVN_ERR(svn_wc__expand_keywords(keywords,
+ db, local_abspath,
+ propval->data,
+ result_pool, scratch_pool));
+ }
+ if (special)
+ {
+ propval = props ? apr_hash_get(props, SVN_PROP_SPECIAL,
+ APR_HASH_KEY_STRING) : NULL;
+
+ *special = (propval != NULL);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__expand_keywords(apr_hash_t **keywords,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *keyword_list,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
+ const char *url;
SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL,
NULL, NULL, &changed_rev,
- &changed_date, &changed_author, NULL, NULL,
+ &changed_date, &changed_author, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- db, local_abspath, scratch_pool, scratch_pool));
+ NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+
SVN_ERR(svn_wc__internal_node_get_url(&url, db, local_abspath,
scratch_pool, scratch_pool));
SVN_ERR(svn_subst_build_keywords2(keywords,
- list,
+ keyword_list,
apr_psprintf(scratch_pool, "%ld",
changed_rev),
url,
@@ -343,26 +343,6 @@ svn_wc__get_keywords(apr_hash_t **keywor
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_wc__get_special(svn_boolean_t *special,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
-{
- const svn_string_t *propval;
-
- /* Get the property value. */
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_wc__internal_propget(&propval, db, local_abspath,
- SVN_PROP_SPECIAL, scratch_pool,
- scratch_pool));
- *special = propval != NULL;
-
- return SVN_NO_ERROR;
-}
-
-
svn_error_t *
svn_wc__maybe_set_executable(svn_boolean_t *did_set,
svn_wc__db_t *db,
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.h?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/translate.h Fri Jul 23 19:37:19 2010
@@ -36,8 +36,9 @@ extern "C" {
/* Newline and keyword translation properties */
-/* Query the SVN_PROP_EOL_STYLE property on file LOCAL_ABSPATH in DB. If
- STYLE is non-null, set *STYLE to LOCAL_ABSPATH's eol style. Set *EOL to
+/* If EOL is not-NULL query the SVN_PROP_EOL_STYLE property on file
+ LOCAL_ABSPATH in DB. If STYLE is non-null, set *STYLE to LOCAL_ABSPATH's
+ eol style. Set *EOL to
- NULL for svn_subst_eol_style_none, or
@@ -50,15 +51,32 @@ extern "C" {
If STYLE is null on entry, ignore it. If *EOL is non-null on exit,
it is a static string not allocated in POOL.
+ If KEYWORDS is not NULL Expand keywords for the file at LOCAL_ABSPATH
+ in DB, by parsing a whitespace-delimited list of keywords. If any keywords
+ are found in the list, allocate *KEYWORDS from RESULT_POOL and populate it
+ with mappings from (const char *) keywords to their (svn_string_t *)
+ values (also allocated in RESULT_POOL).
+
+ If a keyword is in the list, but no corresponding value is
+ available, do not create a hash entry for it. If no keywords are
+ found in the list, or if there is no list, set *KEYWORDS to NULL.
+
+ If SPECIAL is not NULL determine if the svn:special flag is set on LOCAL_ABSPATH
+ in DB. If so, set SPECIAL to TRUE, if not, set it to FALSE
+
Use SCRATCH_POOL for temporary allocation, RESULT_POOL for allocating
*STYLE and *EOL.
*/
-svn_error_t *svn_wc__get_eol_style(svn_subst_eol_style_t *style,
- const char **eol,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
+svn_error_t *
+svn_wc__get_translate_info(svn_subst_eol_style_t *style,
+ const char **eol,
+ apr_hash_t **keywords,
+ svn_boolean_t *special,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* Reverse parser. Given a real EOL string ("\n", "\r", or "\r\n"),
return an encoded *VALUE ("LF", "CR", "CRLF") that one might see in
@@ -67,37 +85,26 @@ void svn_wc__eol_value_from_string(const
const char *eol);
/* Expand keywords for the file at LOCAL_ABSPATH in DB, by parsing a
- whitespace-delimited list of keywords. If any keywords are found
- in the list, allocate *KEYWORDS from RESULT_POOL and populate it with
- mappings from (const char *) keywords to their (svn_string_t *)
+ whitespace-delimited list of keywords KEYWORD_LIST. If any keywords
+ are found in the list, allocate *KEYWORDS from RESULT_POOL and populate
+ it with mappings from (const char *) keywords to their (svn_string_t *)
values (also allocated in RESULT_POOL).
If a keyword is in the list, but no corresponding value is
available, do not create a hash entry for it. If no keywords are
found in the list, or if there is no list, set *KEYWORDS to NULL.
- If FORCE_LIST is non-null, use it as the list; else use the
- SVN_PROP_KEYWORDS property for PATH. In either case, use LOCAL_ABSPATH
- to expand keyword values.
+ Use LOCAL_ABSPATH to expand keyword values.
Use SCRATCH_POOL for any temporary allocations.
*/
-svn_error_t *svn_wc__get_keywords(apr_hash_t **keywords,
- svn_wc__db_t *db,
- const char *local_abspath,
- const char *force_list,
-
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
-
-/* Determine if the svn:special flag is set on LOCAL_ABSPATH in DB. If so,
- set SPECIAL to TRUE, if not, set it to FALSE. Perform any temporary
- allocations in SCRATCH_POOL. */
-svn_error_t *svn_wc__get_special(svn_boolean_t *special,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *scratch_pool);
+svn_error_t *
+svn_wc__expand_keywords(apr_hash_t **keywords,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *keyword_list,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* If the SVN_PROP_EXECUTABLE property is present at all, then set
LOCAL_ABSPATH in DB executable. If DID_SET is non-null, then set
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/update_editor.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/update_editor.c Fri Jul 23 19:37:19 2010
@@ -1029,7 +1029,9 @@ struct file_baton
/* The last-changed-date of the file. This is actually a property
that comes through as an 'entry prop', and will be used to set
- the working file's timestamp if it's added. */
+ the working file's timestamp if it's added.
+
+ Will be NULL unless eb->use_commit_times is TRUE. */
const char *last_changed_date;
/* Bump information for the directory this file lives in */
@@ -1204,7 +1206,7 @@ prep_directory(struct dir_baton *db,
if (!locked_here)
/* Recursive lock release on parent will release this lock. */
SVN_ERR(svn_wc__acquire_write_lock(NULL, db->edit_baton->wc_ctx,
- dir_abspath, pool, pool));
+ dir_abspath, FALSE, pool, pool));
#endif
return SVN_NO_ERROR;
@@ -2333,6 +2335,8 @@ add_directory(const char *path,
svn_wc__db_status_t status;
svn_wc__db_kind_t wc_kind;
svn_boolean_t already_conflicted;
+ svn_boolean_t versioned_locally_and_present;
+ svn_wc_conflict_description2_t *tree_conflict = NULL;
svn_error_t *err;
/* Semantic check. Either both "copyfrom" args are valid, or they're
@@ -2408,25 +2412,6 @@ add_directory(const char *path,
db->ambient_depth = svn_depth_infinity;
}
- /* Is this path a conflict victim? */
- SVN_ERR(node_already_conflicted(&already_conflicted, eb->db,
- db->local_abspath, pool));
- if (already_conflicted)
- {
- /* Record this conflict so that its descendants are skipped silently. */
- SVN_ERR(remember_skipped_tree(eb, db->local_abspath));
-
- db->skip_this = TRUE;
- db->skip_descendants = TRUE;
- db->already_notified = TRUE;
-
- /* ### TODO: Also print victim_path in the skip msg. */
- do_notification(eb, db->local_abspath, svn_node_unknown,
- svn_wc_notify_skip, pool);
-
- return SVN_NO_ERROR;
- }
-
/* It may not be named the same as the administrative directory. */
if (svn_wc_is_adm_dir(db->name, pool))
return svn_error_createf(
@@ -2450,48 +2435,96 @@ add_directory(const char *path,
svn_error_clear(err);
wc_kind = svn_wc__db_kind_unknown;
status = svn_wc__db_status_normal;
+
+ versioned_locally_and_present = FALSE;
}
+ else
+ versioned_locally_and_present = IS_NODE_PRESENT(status);
- /* The path can exist, but it must be a directory. */
- if (kind == svn_node_file || kind == svn_node_unknown ||
- (wc_kind != svn_wc__db_kind_unknown &&
- wc_kind != svn_wc__db_kind_dir && IS_NODE_PRESENT(status)))
+ /* Is this path a conflict victim? */
+ SVN_ERR(node_already_conflicted(&already_conflicted, eb->db,
+ db->local_abspath, pool));
+ if (already_conflicted
+ && status == svn_wc__db_status_not_present
+ && kind == svn_node_none)
{
- db->already_notified = TRUE;
- do_notification(eb, db->local_abspath, svn_node_dir,
- svn_wc_notify_update_obstruction, pool);
-
- return svn_error_createf(
- SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
- _("Failed to add directory '%s': a non-directory object of the "
- "same name already exists"),
- svn_dirent_local_style(db->local_abspath, pool));
+ /* A conflict is flagged. Now let's do some user convenience.
+ * When we flagged a tree conflict for a local unversioned node
+ * vs. an incoming add, and we find that this unversioned node is
+ * no longer in the way, automatically pull in the versioned node
+ * and remove the conflict marker.
+ * Right, the node status matches (not_present) and there is no
+ * unversioned obstruction in the file system (anymore?). If it
+ * has a tree conflict with reason 'unversioned', remove that. */
+ const svn_wc_conflict_description2_t *previous_tc;
+ SVN_ERR(svn_wc__get_tree_conflict(&previous_tc,
+ eb->wc_ctx,
+ db->local_abspath,
+ pool, pool));
+ if (previous_tc
+ && previous_tc->reason == svn_wc_conflict_reason_unversioned)
+ {
+ /* Remove tree conflict. */
+ SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db,
+ db->local_abspath,
+ NULL, pool));
+ /* Don't skip this path after all. */
+ already_conflicted = FALSE;
+ }
}
- if (kind == svn_node_dir &&
- (wc_kind == svn_wc__db_kind_unknown || !IS_NODE_PRESENT(status)))
+ /* Now the "usual" behaviour if already conflicted. Skip it. */
+ if (already_conflicted)
{
- /* Found an unversioned directory */
- db->obstruction_found = TRUE;
+ /* Record this conflict so that its descendants are skipped silently. */
+ SVN_ERR(remember_skipped_tree(eb, db->local_abspath));
- if (!eb->allow_unver_obstructions)
- {
- db->already_notified = TRUE;
- do_notification(eb, db->local_abspath, svn_node_dir,
- svn_wc_notify_update_obstruction, pool);
+ db->skip_this = TRUE;
+ db->skip_descendants = TRUE;
+ db->already_notified = TRUE;
- return svn_error_createf(
- SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
- _("Failed to add directory '%s': an unversioned "
- "directory of the same name already exists"),
- svn_dirent_local_style(db->local_abspath, pool));
- }
+ /* ### TODO: Also print victim_path in the skip msg. */
+ do_notification(eb, db->local_abspath, svn_node_unknown,
+ svn_wc_notify_skip, pool);
+ return SVN_NO_ERROR;
}
- else if (wc_kind == svn_wc__db_kind_dir)
+
+
+ if (versioned_locally_and_present)
{
- /* Directory exists */
- if (IS_NODE_PRESENT(status) &&
- status != svn_wc__db_status_deleted)
+ /* What to do with a versioned or schedule-add dir:
+
+ A dir already added without history is OK. Set add_existed
+ so that user notification is delayed until after any prop
+ conflicts have been found.
+
+ An existing versioned dir is an error. In the future we may
+ relax this restriction and simply update such dirs.
+
+ A dir added with history is a tree conflict. */
+
+ svn_boolean_t local_is_dir;
+ svn_boolean_t local_is_non_dir;
+ const char *local_is_copy = NULL;
+
+ /* Is the local add a copy? */
+ if (status == svn_wc__db_status_added)
+ SVN_ERR(svn_wc__node_get_copyfrom_info(&local_is_copy,
+ NULL, NULL, NULL, NULL,
+ eb->wc_ctx,
+ db->local_abspath,
+ pool, pool));
+
+
+ /* Is there something that is a file? */
+ local_is_dir = (wc_kind == svn_wc__db_kind_dir
+ && status != svn_wc__db_status_deleted);
+
+ /* Is there *something* that is not a dir? */
+ local_is_non_dir = (wc_kind != svn_wc__db_kind_dir
+ && status != svn_wc__db_status_deleted);
+
+ if (local_is_dir)
{
svn_boolean_t wc_root;
svn_boolean_t switched;
@@ -2533,91 +2566,141 @@ add_directory(const char *path,
}
}
- /* What to do with a versioned or schedule-add dir:
-
- A dir already added without history is OK. Set add_existed
- so that user notification is delayed until after any prop
- conflicts have been found.
+ /* We can't properly handle add vs. add with mismatching
+ * node kinds before single db. */
+ if (local_is_non_dir)
+ {
+ db->already_notified = TRUE;
+ do_notification(eb, db->local_abspath, svn_node_dir,
+ svn_wc_notify_update_obstruction, pool);
+ return svn_error_createf(
+ SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+ _("Failed to add directory '%s': a non-directory object "
+ "of the same name already exists"),
+ svn_dirent_local_style(db->local_abspath,
+ pool));
+ }
- An existing versioned dir is an error. In the future we may
- relax this restriction and simply update such dirs.
+ /* Do tree conflict checking if
+ * - if there is a local copy.
+ * - if this is a switch operation
+ * - the node kinds mismatch (when single db is here)
+ *
+ * During switch, local adds at the same path as incoming adds get
+ * "lost" in that switching back to the original will no longer have the
+ * local add. So switch always alerts the user with a tree conflict.
+ *
+ * Allow pulling absent/exluded/not_present nodes back in.
+ *
+ * ### This code is already gearing up to single db with respect to
+ * add-vs.-add conflicts with mismatching node kinds. But before single
+ * db, we cannot deal with mismatching node kinds properly.
+ *
+ * ### We would also like to be checking copyfrom infos to not flag tree
+ * conflicts on two copies with identical history. But at the time of
+ * writing, add_directory() does not get any copyfrom information. */
+ if (! pb->in_deleted_and_tree_conflicted_subtree
+ && (eb->switch_relpath != NULL
+ || local_is_non_dir
+ || local_is_copy
+ )
+ )
+ {
+ SVN_ERR(check_tree_conflict(&tree_conflict, eb,
+ db->local_abspath,
+ svn_wc_conflict_action_add,
+ svn_node_dir, db->new_relpath, pool));
+ }
- A dir added with history is a tree conflict. */
- if (status == svn_wc__db_status_added)
+ if (tree_conflict == NULL)
{
- /* Specialize the added case to added, copied, moved */
- SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, eb->db,
- db->local_abspath, pool, pool));
+ /* We have a node in WORKING and we've decided not to flag a
+ * conflict, so merge it with the incoming add. */
+ db->add_existed = TRUE;
+
+ /* Pre-single-db, a dir that was OS-deleted from the working copy
+ * along with its .svn folder is seen 'obstructed' in this code
+ * path. The particular situation however better matches the word
+ * 'missing'. We do add_existed to avoid spurious errors where other
+ * code relies on add_existed to be TRUE when there is a node
+ * record (schedule_tests delete_redelete_fudgery used to XFail).
+ * Still, let's notify 'A' as the old client did. Ultimately, this
+ * should probably say 'Restored' instead of 'A', like with file. */
+ if (status == svn_wc__db_status_obstructed
+ || status == svn_wc__db_status_obstructed_add
+ || status == svn_wc__db_status_obstructed_delete)
+ {
+ db->already_notified = TRUE;
+ do_notification(eb, db->local_abspath, svn_node_dir,
+ svn_wc_notify_add, pool);
+ }
}
+ }
+ else if (kind != svn_node_none)
+ {
+ /* There's an unversioned node at this path. */
+ db->obstruction_found = TRUE;
- switch (status)
+ /* Unversioned, obstructing dirs are handled by prop merge/conflict,
+ * if unversioned obstructions are allowed. */
+ if (! (kind == svn_node_dir && eb->allow_unver_obstructions))
{
- case svn_wc__db_status_absent:
- case svn_wc__db_status_excluded:
- /* Ignore these hidden states. Allow pulling them (back) in. */
- break;
- case svn_wc__db_status_not_present:
- break;
- case svn_wc__db_status_obstructed:
- case svn_wc__db_status_obstructed_add:
- case svn_wc__db_status_obstructed_delete:
- /* ### In 1.6 we ignored these cases in this block as
- the behavior was just pulling them back in.
+ /* ### Instead of skipping, this should bring in the BASE node
+ * and mark some sort of obstruction-conflict. Come, o single-db! */
+ db->skip_this = TRUE;
- Explicitly handle them as not raising a tree conflict
- now. Will never occur once we have a central DB. */
- break;
- case svn_wc__db_status_added:
- /* ### BH: I think this case should be conditional with something
- like allow_unver_obstructions, as this changes the
- base of locally added files.
- ### BH: Always generate tree conflict? */
- db->add_existed = TRUE;
- break;
- default:
- {
- svn_wc_conflict_description2_t *tree_conflict = NULL;
+ /* If we are skipping an add, we need to tell the WC that
+ * there's a node supposed to be here which we don't have. */
+ SVN_ERR(svn_wc__db_base_add_absent_node(eb->db, db->local_abspath,
+ db->new_relpath,
+ eb->repos_root,
+ eb->repos_uuid,
+ (eb->target_revision?
+ *eb->target_revision
+ : SVN_INVALID_REVNUM),
+ svn_wc__db_kind_dir,
+ svn_wc__db_status_not_present,
+ NULL, NULL, pool));
+ SVN_ERR(remember_skipped_tree(eb, db->local_abspath));
+
+ /* Mark a conflict */
+ SVN_ERR(create_tree_conflict(&tree_conflict, eb,
+ db->local_abspath,
+ svn_wc_conflict_reason_unversioned,
+ svn_wc_conflict_action_add,
+ svn_node_dir,
+ db->new_relpath, pool, pool));
+ SVN_ERR_ASSERT(tree_conflict != NULL);
+ }
+ }
- /* Check for conflicts only when we haven't already recorded
- * a tree-conflict on a parent node. */
- if (!db->in_deleted_and_tree_conflicted_subtree)
- SVN_ERR(check_tree_conflict(&tree_conflict, eb,
- db->local_abspath,
- svn_wc_conflict_action_add,
- svn_node_dir, db->new_relpath, pool));
+ if (tree_conflict != NULL)
+ {
+ svn_skel_t *work_item;
- if (tree_conflict != NULL)
- {
- svn_skel_t *work_item;
+ /* Queue this conflict in the parent so that its descendants
+ are skipped silently. */
+ SVN_ERR(svn_wc__loggy_add_tree_conflict(&work_item,
+ eb->db,
+ pb->local_abspath,
+ tree_conflict,
+ pool));
+ SVN_ERR(svn_wc__db_wq_add(eb->db, pb->local_abspath,
+ work_item, pool));
- /* Queue this conflict in the parent so that its descendants
- are skipped silently. */
- SVN_ERR(svn_wc__loggy_add_tree_conflict(&work_item,
- eb->db,
- pb->local_abspath,
- tree_conflict,
- pool));
- SVN_ERR(svn_wc__db_wq_add(eb->db, pb->local_abspath,
- work_item, pool));
-
- SVN_ERR(remember_skipped_tree(eb, db->local_abspath));
-
- db->skip_this = TRUE;
- db->skip_descendants = TRUE;
- db->already_notified = TRUE;
+ SVN_ERR(remember_skipped_tree(eb, db->local_abspath));
- do_notification(eb, db->local_abspath, svn_node_unknown,
- svn_wc_notify_tree_conflict, pool);
+ db->skip_this = TRUE;
+ db->skip_descendants = TRUE;
+ db->already_notified = TRUE;
- return SVN_NO_ERROR;
- }
- }
- break;
- }
+ do_notification(eb, db->local_abspath, svn_node_unknown,
+ svn_wc_notify_tree_conflict, pool);
+ return SVN_NO_ERROR;
}
+
#ifdef SINGLE_DB
SVN_ERR(svn_wc__db_temp_op_set_new_dir_to_incomplete(eb->db,
db->local_abspath,
@@ -4429,7 +4512,7 @@ static svn_error_t *
change_file_prop(void *file_baton,
const char *name,
const svn_string_t *value,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
struct file_baton *fb = file_baton;
struct edit_baton *eb = fb->edit_baton;
@@ -4446,10 +4529,13 @@ change_file_prop(void *file_baton,
/* Special case: If use-commit-times config variable is set we
cache the last-changed-date propval so we can use it to set
the working file's timestamp. */
- if (eb->use_commit_times
- && (strcmp(name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0)
- && value)
- fb->last_changed_date = apr_pstrdup(fb->pool, value->data);
+ if (value
+ && eb->use_commit_times
+ && (strcmp(name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0))
+ {
+ /* propchange is already in the right pool */
+ fb->last_changed_date = propchange->value->data;
+ }
return SVN_NO_ERROR;
}
@@ -4606,7 +4692,7 @@ merge_file(svn_skel_t **work_items,
FALSE /* compare_textbases */,
pool));
}
- else if (new_text_base_sha1_checksum)
+ else if (new_text_base_sha1_checksum && !fb->obstruction_found)
{
svn_stream_t *pristine_stream;
@@ -4624,8 +4710,13 @@ merge_file(svn_skel_t **work_items,
}
else
{
- /* No other potential changes, so the working file is NOT modified. */
- is_locally_modified = FALSE;
+ /* No other potential changes, so the working file is NOT modified.
+ Except when we have a local obstruction! */
+
+ if (fb->obstruction_found)
+ is_locally_modified = TRUE;
+ else
+ is_locally_modified = FALSE;
}
if (have_base)
@@ -4843,8 +4934,11 @@ merge_file(svn_skel_t **work_items,
apr_hash_t *keywords;
- SVN_ERR(svn_wc__get_keywords(&keywords, eb->db, fb->local_abspath, NULL,
- pool, pool));
+ SVN_ERR(svn_wc__get_translate_info(NULL, NULL,
+ &keywords,
+ NULL,
+ eb->db, fb->local_abspath,
+ pool, pool));
if (magic_props_changed || keywords)
{
/* Special edge-case: it's possible that this file installation
@@ -4885,22 +4979,28 @@ merge_file(svn_skel_t **work_items,
&& !is_locally_modified
&& (fb->adding_file || status == svn_wc__db_status_normal))
{
+ apr_time_t set_date = 0;
/* Adjust working copy file unless this file is an allowed
obstruction. */
if (fb->last_changed_date && !fb->obstruction_found)
{
- SVN_ERR(svn_wc__loggy_set_timestamp(
- &work_item, eb->db, pb->local_abspath,
- fb->local_abspath, fb->last_changed_date,
- pool));
- *work_items = svn_wc__wq_merge(*work_items, work_item, pool);
+ /* Ignore invalid dates */
+ err = svn_time_from_cstring(&set_date, fb->last_changed_date,
+ pool);
+
+ if (err)
+ {
+ svn_error_clear(err);
+ set_date = 0;
+ }
}
- /* ### what if the file is locally-deleted? or if there is an
- ### obstruction. OP_RECORD_FILEINFO will deal with a missing
- ### file, but what if this is NOT our file? (ie. obstruction) */
+ /* If this would have been an obstruction, we wouldn't be here,
+ because we would have installed an obstruction or tree conflict
+ instead */
SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,
fb->local_abspath,
+ set_date,
pool));
*work_items = svn_wc__wq_merge(*work_items, work_item, pool);
}
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/upgrade.c?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/upgrade.c Fri Jul 23 19:37:19 2010
@@ -90,20 +90,33 @@ read_propfile(apr_hash_t **props,
{
svn_error_t *err;
svn_stream_t *stream;
+ apr_finfo_t finfo;
- err = svn_stream_open_readonly(&stream, propfile_abspath,
- scratch_pool, scratch_pool);
- if (err)
- {
- if (!APR_STATUS_IS_ENOENT(err->apr_err))
- return svn_error_return(err);
+ err = svn_io_stat(&finfo, propfile_abspath, APR_FINFO_SIZE, scratch_pool);
+ if (err
+ && (APR_STATUS_IS_ENOENT(err->apr_err)
+ || APR_STATUS_IS_ENOTDIR(err->apr_err)))
+ {
svn_error_clear(err);
/* The propfile was not there. Signal with a NULL. */
*props = NULL;
return SVN_NO_ERROR;
}
+ else
+ SVN_ERR(err);
+
+ /* A 0-bytes file signals an empty property list.
+ (mostly used for revert-props) */
+ if (finfo.size == 0)
+ {
+ *props = apr_hash_make(result_pool);
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_stream_open_readonly(&stream, propfile_abspath,
+ scratch_pool, scratch_pool));
/* ### does this function need to be smarter? will we see zero-length
### files? see props.c::load_props(). there may be more work here.
@@ -468,16 +481,14 @@ wipe_obsolete_files(const char *wcroot_a
scratch_pool),
TRUE, scratch_pool));
-#if (SVN_WC__VERSION >= 17)
/* Remove the old text-base directory and the old text-base files. */
svn_error_clear(svn_io_remove_dir2(
svn_wc__adm_child(wcroot_abspath,
TEXT_BASE_SUBDIR,
scratch_pool),
FALSE, NULL, NULL, scratch_pool));
-#endif
-#if 0 /* ### NOT READY TO WIPE THESE FILES!! */
+#if (SVN_WC__VERSION >= 18)
/* Remove the old properties files... whole directories at a time. */
svn_error_clear(svn_io_remove_dir2(
svn_wc__adm_child(wcroot_abspath,
@@ -964,7 +975,7 @@ migrate_node_props(const char *wcroot_ab
scratch_pool, scratch_pool));
return svn_error_return(svn_wc__db_upgrade_apply_props(
- sdb, name,
+ sdb, wcroot_abspath, name,
base_props, revert_props, working_props,
original_format,
scratch_pool));
@@ -1338,20 +1349,17 @@ upgrade_to_wcng(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_upgrade_apply_dav_cache(sdb, all_wcprops, iterpool));
}
+ SVN_ERR(migrate_text_bases(dir_abspath, sdb, iterpool));
+
+#if (SVN_WC__VERSION >= 18)
/* Upgrade all the properties (including "this dir").
Note: this must come AFTER the entries have been migrated into the
database. The upgrade process needs the children in BASE_NODE and
WORKING_NODE, and to examine the resultant WORKING state. */
-#if 0
- /* ### not quite yet */
SVN_ERR(migrate_props(dir_abspath, sdb, old_format, iterpool));
#endif
-#if (SVN_WC__VERSION >= 17)
- SVN_ERR(migrate_text_bases(dir_abspath, sdb, iterpool));
-#endif
-
/* All done. DB should finalize the upgrade process now. */
SVN_ERR(svn_wc__db_upgrade_finish(dir_abspath, sdb, iterpool));
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-metadata.sql?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-metadata.sql Fri Jul 23 19:37:19 2010
@@ -479,6 +479,137 @@ PRAGMA user_version =
-- define: SVN_WC__VERSION
;
+/* ------------------------------------------------------------------------- */
+
+/* The NODE_DATA table describes the way WORKING nodes are layered on top of
+ BASE nodes and on top of other WORKING nodes, due to nested tree structure
+ changes. The layers are modelled using the "op_depth" column.
+
+ Each row in BASE_NODE has an associated row NODE_DATA. Additionally, each
+ row in WORKING_NODE has one or more associated rows in NODE_DATA.
+
+ This table contains only those data elements which apply to BASE as well as
+ all WORKING layers; fields applicable only to the currently visible WORKING
+ node or BASE node are located in the WORKING_NODE and BASE_NODE tables.
+
+ ### This table is to be integrated into the SCHEMA statement as soon
+ the experimental status of NODE_DATA is lifted.
+
+ For illustration, with a scenario like this:
+
+ # (0)
+ svn rm foo
+ svn cp ^/moo foo # (1)
+ svn rm foo/bar
+ touch foo/bar
+ svn add foo/bar # (2)
+
+ , these are the NODE_DATA for the path foo/bar (before single-db, the
+ numbering of op_depth is still a bit different):
+
+ (0) BASE_NODE -----> NODE_DATA (op_depth == 0)
+ (1) NODE_DATA (op_depth == 1) ( <----_ )
+ (2) NODE_DATA (op_depth == 2) <----- WORKING_NODE
+
+ 0 is the original data for foo/bar before 'svn rm foo' (if it existed).
+ 1 is the data for foo/bar copied in from ^/moo/bar. (There would also be a
+ WORKING_NODE for the path foo, with original_* pointing at ^/moo.)
+ 2 is the to-be-committed data for foo/bar, created by 'svn add foo/bar'.
+
+ An 'svn revert foo/bar' would remove the NODE_DATA of (2) (and possibly
+ rewire the WORKING_NODE to represent a child of the operation (1)).
+ So foo/bar would be a copy of ^/moo/bar again.
+ */
+-- STMT_CREATE_NODE_DATA
+CREATE TABLE NODE_DATA (
+ wc_id INTEGER NOT NULL REFERENCES WCROOT (id),
+ local_relpath TEXT NOT NULL,
+ op_depth INTEGER NOT NULL,
+
+ /* parent's local_relpath for aggregating children of a given parent.
+ this will be "" if the parent is the wcroot. Since a wcroot will
+ never have a WORKING node the parent_relpath will never be null. */
+ /* ### would be nice to make this column NOT NULL. */
+ parent_relpath TEXT,
+
+ /* In case 'op_depth' is equal to 0, this is part of the BASE tree; in
+ that case, all presence values except 'base-deleted' are allowed.
+
+
+ In case 'op_depth' is greater than 0, this is part of a layer of
+ working nodes; in that case, the following presence values apply:
+
+ Is this node "present" or has it been excluded for some reason?
+ Only allowed values: normal, not-present, incomplete, base-deleted.
+ (the others do not make sense for the WORKING tree)
+
+ normal: this node has been added/copied/moved-here. There may be an
+ underlying BASE node at this location, implying this is a replace.
+ Scan upwards from here looking for copyfrom or moved_here values
+ to detect the type of operation constructing this node.
+
+ not-present: the node (or parent) was originally copied or moved-here.
+ A subtree of that source has since been deleted. There may be
+ underlying BASE node to replace. For a move-here or copy-here, the
+ records are simply removed rather than switched to not-present.
+ Note this reflects a deletion only. It is not possible move-away
+ nodes from the WORKING tree. The purported destination would receive
+ a copy from the original source of a copy-here/move-here, or if the
+ nodes were plain adds, those nodes would be shifted to that target
+ for addition.
+
+ incomplete: nodes are being added into the WORKING tree, and the full
+ information about this node is not (yet) present.
+
+ base-deleted: the underlying BASE node has been marked for deletion due
+ to a delete or a move-away (see the moved_to column to determine
+ which), and has not been replaced. */
+ presence TEXT NOT NULL,
+
+ /* the kind of the new node. may be "unknown" if the node is not present. */
+ kind TEXT NOT NULL,
+
+ /* If this node was moved here or copied here, then the following fields may
+ have information about their source node. See BASE_NODE.changed_* for
+ more information.
+
+ For an added or not-present node, these are null. */
+ changed_revision INTEGER,
+ changed_date INTEGER, /* an APR date/time (usec since 1970) */
+ changed_author TEXT,
+
+ /* NULL depth means "default" (typically svn_depth_infinity) */
+ /* ### depth on WORKING? seems this is a BASE-only concept. how do
+ ### you do "files" on an added-directory? can't really ignore
+ ### the subdirs! */
+ /* ### maybe a WC-to-WC copy can retain a depth? */
+ depth TEXT,
+
+ /* The SHA-1 checksum of the pristine text, if this node is a file and was
+ moved here or copied here, else NULL. */
+ checksum TEXT,
+
+ /* for kind==symlink, this specifies the target. */
+ symlink_target TEXT,
+
+ /* Where this node was copied/moved from. All copyfrom_* fields are set
+ only on the root of the operation, and are NULL for all children. */
+ original_repos_id INTEGER REFERENCES REPOSITORY (id),
+ original_repos_path TEXT,
+ original_revision INTEGER,
+
+ /* serialized skel of this node's properties. NULL if we
+ have no information about the properties (a non-present node). */
+ properties BLOB,
+
+ PRIMARY KEY (wc_id, local_relpath, op_depth)
+
+ );
+
+CREATE INDEX I_NODE_PARENT ON NODE_DATA (wc_id, parent_relpath);
+CREATE INDEX I_NODE_PATH ON NODE_DATA (wc_id, local_relpath);
+
+
/* ------------------------------------------------------------------------- */
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-queries.sql?rev=967221&r1=967220&r2=967221&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-queries.sql Fri Jul 23 19:37:19 2010
@@ -77,6 +77,15 @@ insert or replace into base_node (
values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
?15, ?16, ?17);
+-- STMT_INSERT_NODE_DATA
+insert or replace into node_data (
+ wc_id, local_relpath, op_depth, parent_relpath, presence, kind,
+ changed_revision, changed_date, changed_author, depth, checksum,
+ symlink_target, original_repos_id, original_repos_path,
+ original_revision, properties)
+values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12,
+ ?13, ?14, ?15, ?16);
+
-- STMT_INSERT_BASE_NODE_INCOMPLETE
insert or ignore into base_node (
wc_id, local_relpath, parent_relpath, presence, kind, revnum)
@@ -93,6 +102,11 @@ INSERT OR IGNORE INTO WORKING_NODE (
wc_id, local_relpath, parent_relpath, presence, kind)
VALUES (?1, ?2, ?3, 'incomplete', 'unknown');
+-- STMT_INSERT_NODE_DATA_INCOMPLETE
+INSERT OR IGNORE INTO NODE_DATA (
+ wc_id, local_relpath, op_depth, parent_relpath, presence, kind)
+VALUES (?1, ?2, ?3, ?4, 'incomplete', 'unknown');
+
-- STMT_COUNT_BASE_NODE_CHILDREN
SELECT COUNT(*) FROM BASE_NODE
WHERE wc_id = ?1 AND parent_relpath = ?2;
@@ -133,10 +147,21 @@ where wc_id = ?1 and local_relpath = ?2;
update base_node set properties = ?3
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_UPDATE_NODE_DATA_BASE_PROPS
+update node_data set properties = ?3
+where wc_id = ?1 and local_relpath = ?2 and op_depth = 0;
+
-- STMT_UPDATE_WORKING_PROPS
update working_node set properties = ?3
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_UPDATE_NODE_DATA_WORKING_PROPS
+update node_data set properties = ?3
+where wc_id = ?1 and local_relpath = ?2
+ and op_depth in
+ (select max(op_depth) from node_data
+ where wc_id = ?1 and local_relpath = ?2);
+
-- STMT_UPDATE_ACTUAL_PROPS
update actual_node set properties = ?3
where wc_id = ?1 and local_relpath = ?2;
@@ -196,6 +221,12 @@ where copyfrom_repos_id is not null and
(local_relpath = ?2 or
local_relpath like ?3 escape '#');
+-- STMT_UPDATE_NODE_DATA_RECURSIVE_ORIGINAL_REPO
+update node_data set original_repos_id = ?5
+where wc_id = ?1 and original_repos_id = ?4 and
+ (local_relpath = ?2 or
+ local_relpath like ?3 escape '#');
+
-- STMT_UPDATE_LOCK_REPOS_ID
update lock set repos_id = ?4
where repos_id = ?1 and
@@ -259,10 +290,26 @@ VALUES (?1, ?2, ?3, ?4);
delete from base_node
where wc_id = ?1 and local_relpath = ?2;
+/* ### Basically, this query can't exist:
+ we can't be deleting BASE nodes while they still have
+ associated WORKING nodes;
+ at minimum, the op_depth restriction should be removed */
+-- STMT_DELETE_NODE_DATA_BASE
+delete from node_data
+where wc_id = ?1 and local_relpath = ?2 and op_depth = 0;
+
-- STMT_DELETE_WORKING_NODE
delete from working_node
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_DELETE_NODE_DATA_WORKING
+delete from node_data
+where wc_id = ?1 and local_relpath = ?2 and op_depth > 0;
+
+-- STMT_DELETE_NODE_DATA_LAYERS
+delete from node_data
+where wc_id = ?1 and local_relpath = ?2 and op_depth >= ?3;
+
-- STMT_DELETE_ACTUAL_NODE
delete from actual_node
where wc_id = ?1 and local_relpath = ?2;
@@ -271,30 +318,66 @@ where wc_id = ?1 and local_relpath = ?2;
UPDATE BASE_NODE SET depth = ?3
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_UPDATE_NODE_BASE_DEPTH
+UPDATE NODE_DATA SET depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
+
-- STMT_UPDATE_WORKING_DEPTH
UPDATE WORKING_NODE SET depth = ?3
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_UPDATE_NODE_WORKING_DEPTH
+UPDATE NODE_DATA SET depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2 AND
+ op_depth IN (SELECT MAX(op_depth) FROM NODE_DATA
+ WHERE wc_id = ?1 AND local_relpath = ?2);
+
-- STMT_UPDATE_BASE_EXCLUDED
-UPDATE BASE_NODE SET presence = 'excluded', depth = 'infinity'
+UPDATE BASE_NODE SET presence = 'excluded', depth = NULL
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_UPDATE_NODE_BASE_EXCLUDED
+UPDATE NODE_DATA SET presence = 'excluded', depth = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
+
-- STMT_UPDATE_WORKING_EXCLUDED
-UPDATE WORKING_NODE SET presence = 'excluded', depth = 'infinity'
+UPDATE WORKING_NODE SET presence = 'excluded', depth = NULL
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_UPDATE_NODE_WORKING_EXCLUDED
+UPDATE NODE_DATA SET presence = 'excluded', depth = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2 AND
+ op_depth IN (SELECT MAX(op_depth) FROM NODE_DATA
+ WHERE wc_id = ?1 AND local_relpath = ?2);
+
-- STMT_UPDATE_BASE_PRESENCE
update base_node set presence= ?3
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_UPDATE_NODE_BASE_PRESENCE
+update node_data set presence = ?3
+where wc_id = ?1 and local_relpath = ?2 and op_depth = 0;
+
-- STMT_UPDATE_BASE_PRESENCE_KIND
update base_node set presence = ?3, kind = ?4
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_UPDATE_NODE_BASE_PRESENCE_KIND
+update node_data set presence = ?3, kind = ?4
+where wc_id = ?1 and local_relpath = ?2 and op_depth = 0;
+
-- STMT_UPDATE_WORKING_PRESENCE
update working_node set presence = ?3
where wc_id = ?1 and local_relpath =?2;
+-- STMT_UPDATE_NODE_WORKING_PRESENCE
+update node_data set presence = ?3
+where wc_id = ?1 and local_relpath = ?2
+ and op_depth in (select op_depth from node_data
+ where wc_id = ?1 and local_relpath = ?2
+ order by op_depth desc
+ limit 1);
+
-- STMT_UPDATE_BASE_PRESENCE_AND_REVNUM
update base_node set presence = ?3, revnum = ?4
where wc_id = ?1 and local_relpath = ?2;
@@ -581,8 +664,8 @@ SELECT local_relpath FROM WORKING_NODE
WHERE kind = 'file';
-- STMT_PLAN_PROP_UPGRADE
-SELECT 0, null, wc_id FROM BASE_NODE WHERE local_relpath = ?1
-UNION
+SELECT 0, presence, wc_id FROM BASE_NODE WHERE local_relpath = ?1
+UNION ALL
SELECT 1, presence, wc_id FROM WORKING_NODE WHERE local_relpath = ?1;
-- STMT_ATTACH_WCROOT_DB