You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/04/10 12:58:58 UTC
svn commit: r932691 - in /subversion/trunk/subversion:
libsvn_wc/update_editor.c tests/cmdline/depth_tests.py
Author: gstein
Date: Sat Apr 10 10:58:57 2010
New Revision: 932691
URL: http://svn.apache.org/viewvc?rev=932691&view=rev
Log:
Boom! Get rid of a bunch of tweaky edits during update, in favor of a
single atomic add/replace of the BASE node.
This also happens to fix depth_tests 32. Haven't investigated why.
* subversion/libsvn_wc/update_editor.c:
(make_file_baton): ensure that FB->NEW_RELPATH is set. leave a comment
asking why this isn't a simple value derivation.
(loggy_tweak_base_node): die, beyotch.
(merge_file): skip all attempts at entry-based modifications.
(construct_base_node): you die, too, sucka.
(close_file): skip calls to construct_base_ndoe,
svn_wc__db_temp_op_set_base_last_change, and loggy_tweak_base_node.
they all did partial edits of the node, which is... bad. add new code
to call svn_wc__db_base_add_file to insert/replace the BASE node with
all the right values, in one fell swoop. once that is done, then we
jigger around with other crap: maintaining file external data, and
possibly create/delete a corresponding WORKING node.
* subversion/tests/cmdline/depth_tests.py:
(test_list): excluded_path_update_operation now succeeds. seems that we
might be managing the depth value better.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/tests/cmdline/depth_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=932691&r1=932690&r2=932691&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Sat Apr 10 10:58:57 2010
@@ -1029,6 +1029,11 @@ make_file_baton(struct file_baton **f_p,
f->local_abspath,
file_pool, scratch_pool);
+ /* ### why the complicated logic above. isn't it always this way?
+ ### file externals are probably special/different? */
+ if (f->new_relpath == NULL)
+ f->new_relpath = svn_relpath_join(pb->new_relpath, f->name, file_pool);
+
f->pool = file_pool;
f->edit_baton = pb->edit_baton;
f->propchanges = apr_array_make(file_pool, 1, sizeof(svn_prop_t));
@@ -4128,64 +4133,6 @@ change_file_prop(void *file_baton,
}
-
-/* Append to LOG_ACCUM, log commands to update the entry for LOCAL_ABSPATH
- with a NEW_REVISION and a NEW_RELPATH(if non-NULL), making sure
- the entry refers to a file and has no absent or deleted state.
- Use POOL for temporary allocations.
-
- ### REPOS_ROOT must be the current repository root while still using
- entries here */
-static svn_error_t *
-loggy_tweak_base_node(svn_stringbuf_t **log_accum,
- const char *local_abspath,
- svn_revnum_t new_revision,
- const char *repos_root,
- const char *new_relpath,
- apr_pool_t *pool)
-{
- /* Write log entry which will bump the revision number. Also, just
- in case we're overwriting an existing phantom 'deleted' or
- 'absent' entry, be sure to remove the hiddenness. */
- svn_wc_entry_t tmp_entry;
- apr_uint64_t modify_flags = SVN_WC__ENTRY_MODIFY_KIND
- | SVN_WC__ENTRY_MODIFY_REVISION
- | SVN_WC__ENTRY_MODIFY_DELETED
- | SVN_WC__ENTRY_MODIFY_ABSENT
- | SVN_WC__ENTRY_MODIFY_TEXT_TIME
- | SVN_WC__ENTRY_MODIFY_WORKING_SIZE;
-
-
- tmp_entry.revision = new_revision;
- tmp_entry.kind = svn_node_file;
- tmp_entry.deleted = FALSE;
- tmp_entry.absent = FALSE;
- /* Indicate the file was locally modified and we didn't get to
- calculate the true value, but we can't set it to UNKNOWN (-1),
- because that would indicate absense of this value.
- If it isn't locally modified,
- we'll overwrite with the actual value later. */
- tmp_entry.working_size = SVN_WC_ENTRY_WORKING_SIZE_UNKNOWN;
- /* The same is true for the TEXT_TIME field, except that that doesn't
- have an explicid 'changed' value, so we set the value to 'undefined'. */
- tmp_entry.text_time = 0;
-
- /* Possibly install a *non*-inherited URL in the entry. */
- if (new_relpath)
- {
- tmp_entry.url = svn_path_url_add_component2(repos_root, new_relpath,
- pool);
- modify_flags |= SVN_WC__ENTRY_MODIFY_URL;
- }
-
- return svn_error_return(
- svn_wc__loggy_entry_modify(log_accum,
- svn_dirent_dirname(local_abspath, pool),
- local_abspath, &tmp_entry, modify_flags,
- pool, pool));
-}
-
-
/* Write loggy commands to install a text base file from the given temporary
* path TEMP_TEXT_BASE_ABSPATH (which must be in the adm temp area) to the
* given final text-base path FINAL_TEXT_BASE_ABSPATH (which must be the
@@ -4266,8 +4213,6 @@ merge_file(svn_stringbuf_t **log_accum,
svn_boolean_t is_replaced = FALSE;
svn_boolean_t magic_props_changed;
enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
- svn_wc_entry_t tmp_entry;
- apr_uint64_t flags = 0;
/*
When this function is called on file F, we assume the following
@@ -4365,15 +4310,6 @@ merge_file(svn_stringbuf_t **log_accum,
&& ! entry->file_external_path) /* ### EBUG */
is_replaced = TRUE;
- if (fb->add_existed)
- {
- /* Tweak schedule for the file's entry so it is no longer
- scheduled for addition. */
- tmp_entry.schedule = svn_wc_schedule_normal;
- flags |= (SVN_WC__ENTRY_MODIFY_SCHEDULE |
- SVN_WC__ENTRY_MODIFY_FORCE);
- }
-
/* For 'textual' merging, we implement this matrix.
Text file Binary File
@@ -4610,11 +4546,10 @@ merge_file(svn_stringbuf_t **log_accum,
new_text_base_tmp_abspath,
fb->text_base_abspath,
pool, pool));
- tmp_entry.checksum = svn_checksum_to_cstring(new_text_base_md5_checksum,
- pool);
- flags |= SVN_WC__ENTRY_MODIFY_CHECKSUM;
#ifdef SVN_EXPERIMENTAL
+ /* ### this should probably move into close_file. */
+
/* Set the 'checksum' column of the file's BASE_NODE row to
* NEW_TEXT_BASE_SHA1_CHECKSUM. The pristine text identified by that
* checksum is already in the pristine store. */
@@ -4625,18 +4560,7 @@ merge_file(svn_stringbuf_t **log_accum,
#endif
}
- /* If FB->PATH is locally deleted, but not as part of a replacement
- then keep it deleted. */
- if (fb->deleted && !is_replaced)
- {
- tmp_entry.schedule = svn_wc_schedule_delete;
- flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE;
- }
-
- /* Do the entry modifications we've accumulated. */
- SVN_ERR(svn_wc__loggy_entry_modify(log_accum, pb->local_abspath,
- fb->local_abspath, &tmp_entry, flags,
- pool, pool));
+ /* Flush anything that may be residing here. */
SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
/* Log commands to handle text-timestamp and working-size,
@@ -4693,73 +4617,6 @@ merge_file(svn_stringbuf_t **log_accum,
}
-static svn_error_t *
-construct_base_node(svn_wc__db_t *db,
- const char *local_abspath,
- svn_revnum_t target_revision,
- svn_boolean_t resched_normal,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *scratch_pool)
-{
- /* ### HACK: Before we can set properties, we need a node in
- the database. This code could be its own WQ item,
- handling more than just this tweak, but it will
- be removed soon anyway.
-
- ### HACK: The loggy stuff checked the preconditions for us,
- we just make the property code happy here.
-
- We can also clear entry.deleted here, as we are adding a new
- BASE_NODE anyway */
-
- const char *adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- svn_wc_entry_t tmp_entry;
- svn_stringbuf_t *log_accum = NULL;
- apr_uint64_t flags = (SVN_WC__ENTRY_MODIFY_KIND
- | SVN_WC__ENTRY_MODIFY_REVISION
- | SVN_WC__ENTRY_MODIFY_DELETED);
-
- if (resched_normal)
- {
- /* Make sure we have a record in BASE; not in WORKING,
- or we try to install properties in the wrong place */
- flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE | SVN_WC__ENTRY_MODIFY_FORCE;
- tmp_entry.schedule = svn_wc_schedule_normal;
- }
-
- /* ### we can probably just use entry_modify2() rather than adding
- ### a work item, then running it. */
-
- /* Create a very minimalistic file node that will be overridden
- from the loggy operations we have in the file baton log accumulator */
-
- tmp_entry.kind = svn_node_file;
- tmp_entry.revision = target_revision;
- tmp_entry.deleted = FALSE;
-
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum,
- adm_abspath,
- local_abspath,
- &tmp_entry,
- flags,
- scratch_pool, scratch_pool));
-
- SVN_ERR(svn_wc__wq_add_loggy(db, adm_abspath,
- log_accum,
- scratch_pool));
-
- /* ### for now, we use the ADM_ABSPATH even tho a WRI_ABSPATH is all that
- ### is required. BUT: the path must exist, and the file may not.
- ### the directory certainly does tho... */
- SVN_ERR(svn_wc__wq_run(db, adm_abspath,
- cancel_func, cancel_baton,
- scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
/* An svn_delta_editor_t function. */
/* Mostly a wrapper around merge_file. */
static svn_error_t *
@@ -4859,17 +4716,6 @@ close_file(void *file_baton,
_("'%s' is not under version control"),
svn_dirent_local_style(fb->local_abspath, pool));
- /* add_file() was called, or there was an added node here. Ensure that
- we have a BASE node to work with. */
- if (fb->adding_file || fb->add_existed)
- {
- SVN_ERR(construct_base_node(eb->db, fb->local_abspath,
- *eb->target_revision,
- fb->add_existed /* resched_normal */,
- eb->cancel_func, eb->cancel_baton,
- pool));
- }
-
/* Gather the changes for each kind of property. */
SVN_ERR(svn_categorize_props(fb->propchanges, &entry_props, &wc_props,
®ular_props, pool));
@@ -4879,22 +4725,7 @@ close_file(void *file_baton,
eb->db, fb->local_abspath,
entry_props,
pool, pool));
-
- /* ### Hack: The following block should be an atomic operation (including
- ### the install loggy install portions of some functions called above */
SVN_ERR_ASSERT(last_change != NULL); /* files should always have.. */
- SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, fb->local_abspath,
- last_change->cmt_rev,
- last_change->cmt_date,
- last_change->cmt_author,
- pool));
-
- /* Set the new revision and URL in the entry and clean up some other
- fields. This clears DELETED from any prior versioned file with the
- same name (needed before attempting to install props). */
- SVN_ERR(loggy_tweak_base_node(&delayed_log_accum, fb->local_abspath,
- *eb->target_revision,
- eb->repos_root, fb->new_relpath, pool));
/* Install all kinds of properties. It is important to do this before
any file content merging, since that process might expand keywords, in
@@ -4968,8 +4799,92 @@ close_file(void *file_baton,
SVN_WC__FLUSH_LOG_ACCUM(eb->db, fb->dir_baton->local_abspath,
delayed_log_accum, pool);
+ /* Insert/replace the BASE node with all of the new metadata. */
+ {
+ const svn_checksum_t *new_checksum = new_text_base_md5_checksum;
+
+ /* If we don't have a NEW checksum, then the base must not have changed.
+ Just carry over the old checksum. */
+ if (new_checksum == NULL)
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL,
+ &new_checksum, NULL, NULL, NULL,
+ eb->db, fb->local_abspath,
+ pool, pool));
+ }
+
+ SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
+ fb->new_relpath,
+ eb->repos_root, eb->repos_uuid,
+ *eb->target_revision,
+ new_base_props,
+ last_change->cmt_rev,
+ last_change->cmt_date,
+ last_change->cmt_author,
+ new_checksum,
+ SVN_INVALID_FILESIZE,
+ NULL, NULL,
+ pool));
+
+ /* ### ugh. deal with preserving the file external value in the database.
+ ### there is no official API, so we do it this way. maybe we should
+ ### have a temp API into wc_db. */
+ if (entry && entry->file_external_path)
+ {
+ svn_wc_entry_t tmp_entry;
+
+ tmp_entry.file_external_path = entry->file_external_path;
+ tmp_entry.file_external_peg_rev = entry->file_external_peg_rev;
+ tmp_entry.file_external_rev = entry->file_external_rev;
+ SVN_ERR(svn_wc__entry_modify2(eb->db, fb->local_abspath,
+ svn_node_file, FALSE /* parent_stub */,
+ &tmp_entry,
+ SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL,
+ pool));
+ }
+ }
+
+ /* Deal with the WORKING tree, based on updates to the BASE tree. */
+
+ /* An ancestor was locally-deleted. This file is being added within
+ that tree. We need to schedule this file for deletion. */
+ if (fb->dir_baton->in_deleted_and_tree_conflicted_subtree && fb->adding_file)
+ {
+ /* ### temporary hack. we should simply write a WORKING_NODE. */
+
+ svn_wc_entry_t tmp_entry;
+
+ tmp_entry.schedule = svn_wc_schedule_delete;
+ SVN_ERR(svn_wc__entry_modify2(eb->db, fb->local_abspath,
+ svn_node_file, FALSE /* parent_stub */,
+ &tmp_entry, SVN_WC__ENTRY_MODIFY_SCHEDULE,
+ pool));
+ }
+
+ /* This file was locally-added. This file is now being added by the
+ update. We can toss the local-add, turning this into a local-edit. */
+ if (fb->add_existed && fb->adding_file)
+ {
+ /* ### temporary hack. we should simply delete the WORKING_NODE. */
+
+ svn_wc_entry_t tmp_entry;
+
+ /* ### we need to use FORCE to ensure transition to normal. otherwise,
+ ### it would remain in the added state. */
+ tmp_entry.schedule = svn_wc_schedule_normal;
+ SVN_ERR(svn_wc__entry_modify2(eb->db, fb->local_abspath,
+ svn_node_file, FALSE /* parent_stub */,
+ &tmp_entry,
+ SVN_WC__ENTRY_MODIFY_SCHEDULE
+ | SVN_WC__ENTRY_MODIFY_FORCE,
+ pool));
+ }
+
/* ### we may as well run whatever is in the queue right now. this
- ### starts out with some crap node data via construct_base_node(),
+ ### starts out with some crap node data via construct_base_node(),
### so we can't really monkey things up too badly here. all tests
### continue to pass, so this also gives us a better insight into
### doing things more immediately, rather than queuing to run at
Modified: subversion/trunk/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/depth_tests.py?rev=932691&r1=932690&r2=932691&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/depth_tests.py Sat Apr 10 10:58:57 2010
@@ -2694,7 +2694,7 @@ test_list = [ None,
pull_in_tree_with_depth_option,
fold_tree_with_unversioned_modified_items,
depth_empty_update_on_file,
- XFail(excluded_path_update_operation),
+ excluded_path_update_operation,
excluded_path_misc_operation,
excluded_receive_remote_removal,
exclude_keeps_hidden_entries,