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/09/21 16:14:14 UTC
svn commit: r999427 [2/3] - in /subversion/branches/atomic-revprop: ./
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/src/org/tigris/subversion/javahl/
subversion/bindings/java...
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=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/update_editor.c Tue Sep 21 14:14:12 2010
@@ -224,12 +224,6 @@ struct edit_baton
svn_wc_conflict_resolver_func_t conflict_func;
void *conflict_baton;
- /* If the server sends add_file(copyfrom=...) and we don't have the
- copyfrom file in the working copy, we use this callback to fetch
- it directly from the repository. */
- svn_wc_get_file_t fetch_func;
- void *fetch_baton;
-
/* Subtrees that were skipped during the edit, and therefore shouldn't
have their revision/url info updated at the end. If a path is a
directory, its descendants will also be skipped. The keys are absolute
@@ -1969,7 +1963,6 @@ do_entry_deletion(struct edit_baton *eb,
svn_boolean_t conflicted;
svn_wc_conflict_description2_t *tree_conflict = NULL;
const char *dir_abspath = svn_dirent_dirname(local_abspath, pool);
- svn_boolean_t hidden;
svn_skel_t *work_item;
SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
@@ -2153,7 +2146,7 @@ static svn_error_t *
add_directory(const char *path,
void *parent_baton,
const char *copyfrom_path,
- svn_revnum_t copyfrom_revision,
+ svn_revnum_t copyfrom_rev,
apr_pool_t *pool,
void **child_baton)
{
@@ -2168,42 +2161,7 @@ add_directory(const char *path,
svn_wc_conflict_description2_t *tree_conflict = NULL;
svn_error_t *err;
- /* Semantic check. Either both "copyfrom" args are valid, or they're
- NULL and SVN_INVALID_REVNUM. A mixture is illegal semantics. */
- SVN_ERR_ASSERT((copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_revision))
- || (!copyfrom_path &&
- !SVN_IS_VALID_REVNUM(copyfrom_revision)));
- if (copyfrom_path != NULL)
- {
- /* ### todo: for now, this editor doesn't know how to deal with
- copyfrom args. Someday it will interpet them as an update
- optimization, and actually copy one part of the wc to another.
- Then it will recursively "normalize" all the ancestry in the
- copied tree. Someday!
-
- Note from the future: if someday it does, we'll probably want
- to tweak libsvn_ra_neon/fetch.c:validate_element() to accept
- that an add-dir element can contain a delete-entry element
- (because the dir might be added with history). Currently
- that combination will not validate. See r30161, and see the
- thread in which this message appears:
-
- http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=136879
- From: "David Glasser" <gl...@davidglasser.net>
- To: "Karl Fogel" <kf...@red-bean.com>, dev@subversion.tigris.org
- Cc: "Arfrever Frehtes Taifersar Arahesis" <ar...@gmail.com>,
- glasser@tigris.org
- Subject: Re: svn commit: r30161 - in trunk/subversion: \
- libsvn_ra_neon tests/cmdline
- Date: Fri, 4 Apr 2008 14:47:06 -0700
- Message-ID: <1e...@mail.gmail.com>
-
- */
- return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Failed to add directory '%s': "
- "copyfrom arguments not yet supported"),
- svn_dirent_local_style(path, pool));
- }
+ SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));
SVN_ERR(make_dir_baton(&db, path, eb, pb, TRUE, pool));
*child_baton = db;
@@ -2466,15 +2424,12 @@ add_directory(const char *path,
/* 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,
+ SVN_ERR(svn_wc__db_base_add_not_present_node(eb->db, db->local_abspath,
db->new_relpath,
eb->repos_root,
eb->repos_uuid,
- (eb->target_revision?
- *eb->target_revision
- : SVN_INVALID_REVNUM),
+ *eb->target_revision,
svn_wc__db_kind_dir,
- svn_wc__db_status_not_present,
NULL, NULL, pool));
SVN_ERR(remember_skipped_tree(eb, db->local_abspath));
@@ -3113,477 +3068,6 @@ absent_directory(const char *path,
}
-/* Beginning at DIR_ABSPATH within a working copy, search the working copy
- copy for a pre-existing versioned file which is exactly equal to
- COPYFROM_PATH@COPYFROM_REV.
-
- The current implementation does this by taking the repos_relpath of
- dir_abspath and copyfrom_relpath to calculate where in the working copy
- repos_relpath would be and then tries to confirm its guess.
-
- 1) When it finds a copied file there, it looks for its origin to see
- if the origin matches the copied file good enough to use it as new base
- contents and properties. If that is the case set NEW_BASE_CONTENTS
- and NEW_BASE_PROPS to the found restult.
-
- If the new base information is found check if the node is tree-conflicted,
- and when that is the case use its in-wc contents and actual properties
- to set NEW_CONTENTS and NEW_PROPS.
-
- (If new base info is found, return)
-
- 2) If the node's BASE information matches the expected origin matches the the
- copy origin good enough use it as NEW_BASE_CONTENTS and NEW_BASE_PROPS.
-
- If the new base information is found and the db_status of the node is normal,
- then set NEW_CONTENTS and NEW_PROPS with the found values.
-
- If data is not found, its values will be set to NULL.
-
- Allocate the return values in RESULT_POOL, but perform all temporary allocations
- in SCRATCH_POOL.
-
- ### With a centralized datastore this becomes much easier. For now we
- ### keep the old algorithm because the result is also used for copying
- ### local changes. This support can probably be removed once we have real
- ### local file moves.
-*/
-static svn_error_t *
-locate_copyfrom(svn_stream_t **new_base_contents,
- svn_stream_t **new_contents,
- apr_hash_t **new_base_props,
- apr_hash_t **new_props,
- svn_wc__db_t *db,
- const char *dir_abspath,
- const char *copyfrom_relpath,
- svn_revnum_t copyfrom_rev,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- const char *ancestor_abspath, *ancestor_relpath;
- const char *dir_repos_relpath, *dir_repos_root_url, *dir_repos_uuid;
- const char *repos_relpath, *repos_root_url, *repos_uuid;
- const char *local_abspath;
-
- apr_size_t levels_up;
- svn_error_t *err;
-
- SVN_ERR_ASSERT(copyfrom_relpath[0] != '/');
-
- SVN_ERR(svn_wc__db_scan_base_repos(&dir_repos_relpath, &dir_repos_root_url,
- &dir_repos_uuid,
- db, dir_abspath,
- scratch_pool, scratch_pool));
-
- /* Be pessimistic. This function is basically a series of tests
- that gives dozens of ways to fail our search, returning
- SVN_NO_ERROR in each case. If we make it all the way to the
- bottom, we have a real discovery to return. */
- *new_base_contents = NULL;
- *new_contents = NULL;
- *new_base_props = NULL;
- *new_props = NULL;
-
- /* Subtract the dest_dir's URL from the repository "root" URL to get
- the absolute FS path represented by dest_dir. */
-
- /* Find nearest FS ancestor dir of current FS path and copyfrom_parent */
- ancestor_relpath = svn_relpath_get_longest_ancestor(dir_repos_relpath,
- copyfrom_relpath,
- scratch_pool);
-
- /* Move 'up' the working copy to what ought to be the common ancestor dir. */
- levels_up = svn_path_component_count(dir_repos_relpath)
- - svn_path_component_count(ancestor_relpath);
-
- /* Walk up the path dirent safe */
- ancestor_abspath = dir_abspath;
- while (levels_up-- > 0)
- ancestor_abspath = svn_dirent_dirname(ancestor_abspath, scratch_pool);
-
- /* Verify hypothetical ancestor */
- err = svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
- &repos_uuid,
- db, ancestor_abspath,
- scratch_pool, scratch_pool);
-
- if (err && ((err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY) ||
- (err->apr_err == SVN_ERR_WC_PATH_FOUND)))
- {
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- else
- SVN_ERR(err);
-
- /* If we got this far, we know that the ancestor dir exists, and
- that it's a working copy too. But is it from the same
- repository? And does it represent the URL we expect it to? */
- if ((strcmp(dir_repos_uuid, repos_uuid) != 0)
- || (strcmp(dir_repos_root_url, repos_root_url) != 0)
- || (strcmp(ancestor_relpath, repos_relpath) != 0))
- return SVN_NO_ERROR;
-
- /* Add the remaining components to cwd, then add the remaining relpath to
- where we hope the copyfrom_relpath file exists. */
- local_abspath = svn_dirent_join(ancestor_abspath,
- svn_dirent_skip_ancestor(ancestor_relpath,
- copyfrom_relpath),
- scratch_pool);
-
- /* Verify file in expected location */
- {
- svn_revnum_t rev, changed_rev;
- svn_wc__db_status_t status, base_status;
- svn_boolean_t conflicted, have_base;
- const svn_checksum_t *checksum;
-
- err = svn_wc__db_read_info(&status, NULL, &rev, &repos_relpath,
- &repos_root_url, &repos_uuid, &changed_rev,
- NULL, NULL, NULL, NULL, &checksum, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, &have_base,
- NULL, &conflicted, NULL,
- db, local_abspath, scratch_pool, scratch_pool);
-
- if (err && ((err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY ||
- (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND))))
- {
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- else
- SVN_ERR(err);
-
- /* Check if we have an added node with the right copyfrom information, as
- this is what you would see on a file move. */
-
- if (status == svn_wc__db_status_added)
- {
- const char *op_root_abspath;
- const char *original_repos_relpath, *original_root_url;
- const char *original_uuid;
- svn_revnum_t original_rev;
-
- SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath,
- &repos_relpath, &repos_root_url,
- &repos_uuid, &original_repos_relpath,
- &original_root_url, &original_uuid,
- &original_rev,
- db, local_abspath,
- scratch_pool, scratch_pool));
-
- if (status == svn_wc__db_status_copied
- || status == svn_wc__db_status_moved_here)
- {
- original_repos_relpath = svn_relpath_join(
- original_repos_relpath,
- svn_dirent_skip_ancestor(op_root_abspath,
- local_abspath),
- scratch_pool);
-
- /* If the repository location matches our exact guess and
- the file's recorded revisions tell us that the file had the
- same contents at the copyfrom_revision, we can use this
- data as new_base */
- if (strcmp(original_repos_relpath, copyfrom_relpath) == 0
- && strcmp(original_root_url, dir_repos_root_url) == 0
- && strcmp(original_uuid, dir_repos_uuid) == 0
- && strcmp(repos_relpath, copyfrom_relpath) == 0
- && strcmp(repos_root_url, dir_repos_root_url) == 0
- && strcmp(repos_uuid, dir_repos_uuid) == 0
-
- && SVN_IS_VALID_REVNUM(changed_rev)
- && changed_rev <= copyfrom_rev
- && copyfrom_rev <= original_rev)
- {
- svn_node_kind_t kind;
- svn_boolean_t text_changed;
-
- /* WORKING_NODE has the right new-BASE information,
- so we have at least a partial result. */
- SVN_ERR(svn_wc__db_pristine_read(new_base_contents,
- db, local_abspath, checksum,
- result_pool, scratch_pool));
- SVN_ERR(svn_wc__get_pristine_props(new_base_props,
- db, local_abspath,
- result_pool, scratch_pool));
-
- /* If the node is conflicted, that might have happened because
- the node was deleted. Which might indicate that we have
- a file move. In this case we like the real file data */
- if (!conflicted
- && status == svn_wc__db_status_copied)
- return SVN_NO_ERROR; /* A local copy is no local modification
- that we should keep */
-
- /* ### TODO: Add verification to check that the conflict
- tells us that this is the right thing to do.
-
- ### Pre 1.7 we just assumed that it is ok without checking for
- conflicts, so this is not a regression */
-
- SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
-
- if (kind != svn_node_file)
- return SVN_NO_ERROR; /* Nothing to copy */
-
- SVN_ERR(svn_wc__internal_text_modified_p(&text_changed, db,
- local_abspath, FALSE,
- TRUE, scratch_pool));
-
- if (!text_changed)
- return SVN_NO_ERROR; /* Take the easy route */
-
- SVN_ERR(svn_stream_open_readonly(new_contents, local_abspath,
- result_pool, scratch_pool));
-
- SVN_ERR(svn_wc__get_actual_props(new_props, db, local_abspath,
- result_pool, scratch_pool));
-
- return SVN_NO_ERROR;
- }
- }
- }
-
- if (!have_base)
- return SVN_NO_ERROR;
-
- base_status = status;
-
- if (status != svn_wc__db_status_normal)
- SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, &rev,
- &repos_relpath, &repos_root_url,
- &repos_uuid, &changed_rev, NULL,
- NULL, NULL, NULL, &checksum, NULL,
- NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
-
- if (base_status != svn_wc__db_status_normal)
- return SVN_NO_ERROR; /* No interesting BASE_NODE */
-
- if (!repos_relpath || !repos_root_url || !repos_uuid)
- SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
- &repos_uuid,
- db, local_abspath,
- scratch_pool, scratch_pool));
-
- /* Is it from the same repository */
- if ((strcmp(dir_repos_uuid, repos_uuid) != 0)
- || (strcmp(dir_repos_root_url, repos_root_url) != 0)
- || (strcmp(copyfrom_relpath, repos_relpath) != 0))
- return SVN_NO_ERROR;
-
- /* Ok, we know that we look at the right node, but do we have the
- right revision?
-
- To be sure that the base node has the right properties and text,
- the node must be the same in copyfrom_rev and changed_rev, which
- is only true within this specific range
- */
- if (!(SVN_IS_VALID_REVNUM(changed_rev)
- && changed_rev <= copyfrom_rev
- && copyfrom_rev <= rev))
- {
- return SVN_NO_ERROR;
- }
-
- /* BASE_NODE has the right new-BASE information,
- so we have at least a partial result. */
- SVN_ERR(svn_wc__db_pristine_read(new_base_contents,
- db, local_abspath, checksum,
- result_pool, scratch_pool));
-
- SVN_ERR(svn_wc__db_base_get_props(new_base_props,
- db, local_abspath, result_pool,
- scratch_pool));
-
- /* If the node is in status normal, the user probably intended to make
- a copy of this in-wc node, so copy its local changes over to
- the new file. */
- if (status == svn_wc__db_status_normal)
- {
- svn_node_kind_t kind;
- svn_boolean_t text_changed;
-
- SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
-
- if (kind != svn_node_file)
- return SVN_NO_ERROR; /* Nothing to copy */
-
- SVN_ERR(svn_wc__internal_text_modified_p(&text_changed, db,
- local_abspath, FALSE,
- TRUE, scratch_pool));
-
- if (!text_changed)
- return SVN_NO_ERROR; /* Take the easy route */
-
- SVN_ERR(svn_stream_open_readonly(new_contents, local_abspath,
- result_pool, scratch_pool));
-
- SVN_ERR(svn_wc__get_actual_props(new_props, db, local_abspath,
- result_pool, scratch_pool));
- }
- }
- return SVN_NO_ERROR;
-}
-
-
-/* Given a set of properties PROPS_IN, find all regular properties
- and shallowly copy them into a new set (allocate the new set in
- POOL, but the set's members retain their original allocations). */
-static apr_hash_t *
-copy_regular_props(apr_hash_t *props_in,
- apr_pool_t *pool)
-{
- apr_hash_t *props_out = apr_hash_make(pool);
- apr_hash_index_t *hi;
-
- for (hi = apr_hash_first(pool, props_in); hi; hi = apr_hash_next(hi))
- {
- const char *propname = svn__apr_hash_index_key(hi);
- const svn_string_t *propval = svn__apr_hash_index_val(hi);
-
- if (svn_wc_is_normal_prop(propname))
- apr_hash_set(props_out, propname, APR_HASH_KEY_STRING, propval);
- }
- return props_out;
-}
-
-
-/* Do the "with history" part of add_file().
-
- Attempt to locate COPYFROM_PATH@COPYFROM_REV within the existing working
- copy. If a node with such a base is found, copy the base *and working*
- text and properties from there. If not found, fetch the text and
- properties from the repository by calling PB->edit_baton->fetch_func.
-
- Store the copied base and working text in new temporary files in the adm
- tmp area of the parent directory, whose baton is PB. Set
- TFB->copied_text_base_* and TFB->copied_working_text to their paths and
- checksums. Set TFB->copied_*_props to the copied properties.
-
- After this function returns, subsequent apply_textdelta() commands coming
- from the server may further alter the file before it is installed.
-
- Ensure the resulting text base is in the pristine store, and set
- TFB->copied_text_base_* to its readable abspath and checksums.
-*/
-static svn_error_t *
-add_file_with_history(struct dir_baton *pb,
- const char *copyfrom_path,
- svn_revnum_t copyfrom_rev,
- struct file_baton *tfb,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- struct edit_baton *eb = pb->edit_baton;
- svn_stream_t *copied_stream;
- const char *copied_text_base_tmp_abspath;
- svn_wc__db_t *db = eb->db;
- svn_stream_t *new_base_contents, *new_contents;
- apr_hash_t *new_base_props, *new_props;
-
- SVN_ERR_ASSERT(copyfrom_path[0] == '/');
-
- tfb->added_with_history = TRUE;
-
- /* Attempt to locate the copyfrom_path in the working copy first. */
- SVN_ERR(locate_copyfrom(&new_base_contents, &new_contents,
- &new_base_props, &new_props,
- db, pb->local_abspath,
- copyfrom_path+1, /* Create repos_relpath */
- copyfrom_rev, result_pool, scratch_pool));
-
- /* Open the text base for writing (this will get us a temporary file). */
- SVN_ERR(svn_wc__open_writable_base(&copied_stream,
- &copied_text_base_tmp_abspath,
- /* Compute an MD5 checksum for the stream as we write stuff into it.
- ### this is temporary. in many cases, we already *know* the checksum
- ### since it is a copy. */
- &tfb->copied_text_base_md5_checksum,
- &tfb->copied_text_base_sha1_checksum,
- db, pb->local_abspath,
- result_pool, scratch_pool));
-
- if (new_base_contents && new_base_props)
- {
- /* Copy the existing file's text-base over to the (temporary)
- new text-base, where the file baton expects it to be. Get
- the text base and props from the usual place or from the
- revert place, depending on scheduling. */
- SVN_ERR(svn_stream_copy3(new_base_contents, copied_stream,
- eb->cancel_func, eb->cancel_baton,
- scratch_pool));
-
- if (!new_props)
- new_props = new_base_props;
- }
- else /* Couldn't find a file to copy */
- {
- /* Fall back to fetching it from the repository instead. */
-
- if (! eb->fetch_func)
- return svn_error_create(SVN_ERR_WC_INVALID_OP_ON_CWD, NULL,
- _("No fetch_func supplied to update_editor"));
-
- /* Fetch the repository file's text-base and base-props;
- svn_stream_close() automatically closes the text-base file for us. */
-
- /* copyfrom_path is a absolute path, fetch_func requires a path relative
- to the root of the repository so skip the first '/'. */
- SVN_ERR(eb->fetch_func(eb->fetch_baton, copyfrom_path + 1, copyfrom_rev,
- copied_stream,
- NULL, &new_base_props, scratch_pool));
- SVN_ERR(svn_stream_close(copied_stream));
-
- /* Filter out wc-props */
- /* ### Do we get new values as modification or should these really
- be installed? */
- new_base_props = svn_prop_hash_dup(copy_regular_props(new_base_props,
- scratch_pool),
- result_pool);
-
- new_props = new_base_props;
- }
-
- SVN_ERR(svn_wc__db_pristine_install(db, copied_text_base_tmp_abspath,
- tfb->copied_text_base_sha1_checksum,
- tfb->copied_text_base_md5_checksum,
- scratch_pool));
-
- tfb->copied_base_props = new_base_props;
- /* ### Currently we always have to set this even though we don't have
- a real copy, or update_tests.py 60 "add_moved_file_has_props" fails
- */
- tfb->copied_working_props = new_props;
-
- if (new_contents)
- {
- /* If we copied an existing file over, we need to copy its
- working text too, to preserve any local mods. (We already
- read its working *props* into tfb->copied_working_props.) */
- const char *temp_dir_abspath;
- svn_stream_t *tmp_contents;
-
- /* Make a unique file name for the copied working text. */
- SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath,
- db, pb->local_abspath,
- scratch_pool, scratch_pool));
-
- SVN_ERR(svn_stream_open_unique(&tmp_contents, &tfb->copied_working_text,
- temp_dir_abspath, svn_io_file_del_none,
- result_pool, scratch_pool));
-
- SVN_ERR(svn_stream_copy3(new_contents, tmp_contents, eb->cancel_func,
- eb->cancel_baton,
- scratch_pool));
- }
-
- return SVN_NO_ERROR;
-}
-
-
/* An svn_delta_editor_t function. */
static svn_error_t *
add_file(const char *path,
@@ -3605,11 +3089,7 @@ add_file(const char *path,
svn_wc_conflict_description2_t *tree_conflict = NULL;
svn_error_t *err;
- /* Semantic check. Either both "copyfrom" args are valid, or they're
- NULL and SVN_INVALID_REVNUM. A mixture is illegal semantics. */
- SVN_ERR_ASSERT((copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
- || (!copyfrom_path &&
- !SVN_IS_VALID_REVNUM(copyfrom_rev)));
+ SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));
SVN_ERR(make_file_baton(&fb, pb, path, TRUE, pool));
*file_baton = fb;
@@ -3839,15 +3319,12 @@ add_file(const char *path,
/* 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, fb->local_abspath,
+ SVN_ERR(svn_wc__db_base_add_not_present_node(eb->db, fb->local_abspath,
fb->new_relpath,
eb->repos_root,
eb->repos_uuid,
- (eb->target_revision?
- *eb->target_revision
- : SVN_INVALID_REVNUM),
+ *eb->target_revision,
svn_wc__db_kind_file,
- svn_wc__db_status_not_present,
NULL, NULL, subpool));
SVN_ERR(remember_skipped_tree(eb, fb->local_abspath));
@@ -3876,13 +3353,6 @@ add_file(const char *path,
svn_wc_notify_tree_conflict, subpool);
}
- /* Now, if this is an add with history, do the history part. */
- if (copyfrom_path && !fb->skip_this)
- {
- SVN_ERR(add_file_with_history(pb, copyfrom_path, copyfrom_rev,
- fb, pool, subpool));
- }
-
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
@@ -5577,8 +5047,6 @@ make_editor(svn_revnum_t *target_revisio
void *conflict_baton,
svn_wc_external_update_t external_func,
void *external_baton,
- svn_wc_get_file_t fetch_func,
- void *fetch_baton,
const char *diff3_cmd,
const apr_array_header_t *preserved_exts,
const svn_delta_editor_t **editor,
@@ -5653,8 +5121,6 @@ make_editor(svn_revnum_t *target_revisio
eb->cancel_baton = cancel_baton;
eb->conflict_func = conflict_func;
eb->conflict_baton = conflict_baton;
- eb->fetch_func = fetch_func;
- eb->fetch_baton = fetch_baton;
eb->allow_unver_obstructions = allow_unver_obstructions;
eb->skipped_trees = apr_hash_make(edit_pool);
eb->ext_patterns = preserved_exts;
@@ -5724,8 +5190,6 @@ svn_wc_get_update_editor4(const svn_delt
svn_boolean_t allow_unver_obstructions,
const char *diff3_cmd,
const apr_array_header_t *preserved_exts,
- svn_wc_get_file_t fetch_func,
- void *fetch_baton,
svn_wc_conflict_resolver_func_t conflict_func,
void *conflict_baton,
svn_wc_external_update_t external_func,
@@ -5744,7 +5208,6 @@ svn_wc_get_update_editor4(const svn_delt
cancel_func, cancel_baton,
conflict_func, conflict_baton,
external_func, external_baton,
- fetch_func, fetch_baton,
diff3_cmd, preserved_exts, editor, edit_baton,
result_pool, scratch_pool);
}
@@ -5763,8 +5226,6 @@ svn_wc_get_switch_editor4(const svn_delt
svn_boolean_t allow_unver_obstructions,
const char *diff3_cmd,
const apr_array_header_t *preserved_exts,
- svn_wc_get_file_t fetch_func,
- void *fetch_baton,
svn_wc_conflict_resolver_func_t conflict_func,
void *conflict_baton,
svn_wc_external_update_t external_func,
@@ -5786,7 +5247,6 @@ svn_wc_get_switch_editor4(const svn_delt
cancel_func, cancel_baton,
conflict_func, conflict_baton,
external_func, external_baton,
- fetch_func, fetch_baton,
diff3_cmd, preserved_exts,
editor, edit_baton,
result_pool, scratch_pool);
@@ -5909,11 +5369,10 @@ svn_wc__check_wc_root(svn_boolean_t *wc_
svn_wc__db_status_t status;
svn_wc__db_kind_t my_kind;
- /* Go ahead and initialize our return value to the most common
- (code-wise) values. */
if (!kind)
kind = &my_kind;
+ /* Initialize our return values to the most common (code-wise) values. */
*wc_root = TRUE;
if (switched)
*switched = FALSE;
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=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-metadata.sql Tue Sep 21 14:14:12 2010
@@ -384,8 +384,8 @@ CREATE TABLE WORKING_NODE (
parent_relpath TEXT,
/* 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)
+ Only allowed values: normal, not-present, incomplete, base-deleted,
+ excluded. (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.
@@ -407,7 +407,11 @@ CREATE TABLE WORKING_NODE (
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. */
+ which), and has not been replaced.
+
+ excluded: this node is administratively excluded (sparse WC). This must
+ be a child (or grandchild etc.) of a copied directory.
+ */
presence TEXT NOT NULL,
/* the kind of the new node. may be "unknown" if the node is not present. */
@@ -732,8 +736,8 @@ CREATE TABLE NODES (
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:
- Only allowed values: normal, not-present, incomplete, base-deleted.
- (the others do not make sense for the WORKING tree)
+ Only allowed values: normal, not-present, incomplete, base-deleted,
+ excluded. (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.
@@ -755,7 +759,11 @@ CREATE TABLE NODES (
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. */
+ which), and has not been replaced.
+
+ excluded: this node is administratively excluded (sparse WC). This must
+ be a child (or grandchild etc.) of a copied directory.
+ */
presence TEXT NOT NULL,
/* NULL depth means "default" (typically svn_depth_infinity) */
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=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc-queries.sql Tue Sep 21 14:14:12 2010
@@ -68,6 +68,15 @@ select presence, kind, checksum, transla
from working_node
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_SELECT_WORKING_NODE_1
+select presence, kind, checksum, translated_size,
+ changed_revision, changed_date, changed_author, depth, symlink_target,
+ repos_id, repos_path, revision,
+ moved_here, moved_to, last_mod_time, properties
+from nodes
+where wc_id = ?1 and local_relpath = ?2 and op_depth > 0 order by op_depth desc
+limit 1;
+
-- STMT_SELECT_ACTUAL_NODE
select prop_reject, changelist, conflict_old, conflict_new,
conflict_working, tree_conflict_data, properties
@@ -147,10 +156,19 @@ where wc_id = ?1 and local_relpath = ?2;
select properties from base_node
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_SELECT_BASE_PROPS_1
+select properties from nodes
+where wc_id = ?1 and local_relpath = ?2 and op_depth = 0;
+
-- STMT_SELECT_WORKING_PROPS
SELECT properties, presence FROM WORKING_NODE
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_SELECT_WORKING_PROPS_1
+SELECT properties, presence FROM NODES
+WHERE wc_id = ?1 AND local_relpath = ?2
+AND op_depth > 0 ORDER BY op_depth DESC LIMIT 1;
+
-- STMT_SELECT_ACTUAL_PROPS
select properties from actual_node
where wc_id = ?1 and local_relpath = ?2;
@@ -213,10 +231,6 @@ left outer join base_node on base_node.w
and base_node.local_relpath = working_node.local_relpath
where working_node.wc_id = ?1 and working_node.local_relpath = ?2;
--- STMT_SELECT_PARENT_STUB_INFO
-select presence = 'not-present', revnum from base_node
-where wc_id = ?1 and local_relpath = ?2;
-
-- STMT_DELETE_LOCK
delete from lock
where repos_id = ?1 and repos_relpath = ?2;
@@ -620,11 +634,31 @@ UPDATE WORKING_NODE SET
copyfrom_revnum = null
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_UPDATE_COPYFROM_TO_INHERIT_1
+UPDATE NODES SET
+ repos_id = null,
+ repos_path = null,
+ revision = null
+WHERE wc_id = ?1 AND local_relpath = ?2
+ AND op_depth IN (SELECT op_depth FROM nodes
+ WHERE wc_id = ?1 AND local_relpath = ?2
+ ORDER BY op_depth DESC
+ LIMIT 1);
+
-- STMT_DETERMINE_TREE_FOR_RECORDING
SELECT 0 FROM BASE_NODE WHERE wc_id = ?1 AND local_relpath = ?2
UNION
SELECT 1 FROM WORKING_NODE WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_DETERMINE_TREE_FOR_RECORDING_1
+SELECT 0 FROM NODES WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
+UNION
+SELECT 1 FROM NODES WHERE wc_id = ?1 AND local_relpath = ?2
+ AND op_depth IN (SELECT op_depth FROM nodes
+ WHERE wc_id = ?1 AND local_relpath = ?2
+ ORDER BY op_depth DESC
+ LIMIT 1);
+
/* ### Why can't this query not just use the BASE repository
location values, instead of taking 3 additional parameters?! */
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.c Tue Sep 21 14:14:12 2010
@@ -404,7 +404,26 @@ assert_text_columns_equal(svn_sqlite__st
return SVN_NO_ERROR;
}
-#endif
+static svn_error_t *
+assert_blob_columns_equal(svn_sqlite__stmt_t *stmt1,
+ svn_sqlite__stmt_t *stmt2,
+ int column,
+ apr_pool_t *scratch_pool)
+{
+ apr_size_t len1, len2;
+ const void *val1 = svn_sqlite__column_blob(stmt1, column, &len1, NULL);
+ const void *val2 = svn_sqlite__column_blob(stmt2, column, &len2, NULL);
+
+ if (!len1 && !len2)
+ return SVN_NO_ERROR;
+
+ if (len1 != len2 || memcmp(val1, val2, len1))
+ return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+ "Blob of length %ld in statement 1 differs "
+ "from blob of length %ld in statement 2",
+ len1, len2);
+ return SVN_NO_ERROR;
+}
static svn_error_t *
assert_base_rows_match(svn_boolean_t have_row1,
@@ -455,14 +474,77 @@ assert_base_rows_match(svn_boolean_t hav
SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 12)
== svn_sqlite__column_int64(stmt2, 12));
- /* 14: verify props? */
+ /* verify props */
+ SVN_ERR(assert_blob_columns_equal(stmt1, stmt2, 13, scratch_pool));
}
return SVN_NO_ERROR;
}
+static svn_error_t *
+assert_working_rows_match(svn_boolean_t have_row1,
+ svn_boolean_t have_row2,
+ svn_sqlite__stmt_t *stmt1,
+ svn_sqlite__stmt_t *stmt2,
+ const char *relpath,
+ apr_pool_t *scratch_pool)
+{
+ if (have_row1 != have_row2)
+ SVN_ERR(svn_error_createf(
+ SVN_ERR_WC_CORRUPT, NULL,
+ "Different results from WORKING (%d) and NODES queries (%d), "
+ "for local_relpath %s",
+ have_row1, have_row2, relpath));
+
+ if (!have_row1)
+ return SVN_NO_ERROR;
+
+ /* presence */
+ SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 0, scratch_pool));
+ /* kind */
+ SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 1, scratch_pool));
+ /* checksum */
+ SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 2, scratch_pool));
+ /* translated_size */
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 3)
+ == svn_sqlite__column_int64(stmt2, 3));
+ /* changed_rev */
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 4)
+ == svn_sqlite__column_int64(stmt2, 4));
+ /* changed_date */
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 5)
+ == svn_sqlite__column_int64(stmt2, 5));
+ /* changed_author */
+ SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 6, scratch_pool));
+ /* depth */
+ SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 7, scratch_pool));
+ /* symlink_target */
+ /* copyfrom_repos_id */
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 9)
+ == svn_sqlite__column_int64(stmt2, 9));
+ /* copyfrom_repos_path */
+ SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 7, scratch_pool));
+ /* copyfrom_revnum */
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 11)
+ == svn_sqlite__column_int64(stmt2, 11));
+ /* moved_here */
+ /* moved_to */
+ /* last_mod_time */
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 14)
+ == svn_sqlite__column_int64(stmt2, 14));
+ /* properties */
+#if 0
+ /* Disabled for now as base-deleted don't match */
+ SVN_ERR(assert_blob_columns_equal(stmt1, stmt2, 15, scratch_pool));
#endif
+ return SVN_NO_ERROR;
+}
+
+#endif /* SVN_WC__NODES_ONLY */
+
+#endif /* SVN_WC__NODES */
+
/* Scan from LOCAL_RELPATH upwards through parent nodes until we find a parent
that has values in the 'repos_id' and 'repos_relpath' columns. Return
that information in REPOS_ID and REPOS_RELPATH (either may be NULL).
@@ -526,6 +608,10 @@ scan_upwards_for_repos(apr_int64_t *repo
stmt, data_stmt,
current_relpath,
scratch_pool));
+ SVN_ERR(svn_sqlite__reset(data_stmt));
+#else
+ have_row = have_data_row;
+ stmt = data_stmt;
#endif
#endif
@@ -551,7 +637,6 @@ scan_upwards_for_repos(apr_int64_t *repo
}
#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__reset(data_stmt));
#endif
return svn_error_compose_create(err, svn_sqlite__reset(stmt));
}
@@ -572,14 +657,8 @@ scan_upwards_for_repos(apr_int64_t *repo
NULL),
relpath_suffix,
result_pool);
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__reset(data_stmt));
-#endif
return svn_sqlite__reset(stmt);
}
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__reset(data_stmt));
-#endif
#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__reset(stmt));
#endif
@@ -697,7 +776,9 @@ static svn_error_t *
insert_base_node(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
{
const insert_base_baton_t *pibb = baton;
+#ifndef SVN_WC__NODES_ONLY
svn_sqlite__stmt_t *stmt;
+#endif
#ifdef SVN_WC__NODES
svn_sqlite__stmt_t *stmt_node;
#endif
@@ -757,7 +838,6 @@ insert_base_node(void *baton, svn_sqlite
#ifdef SVN_WC__NODES
SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb, STMT_INSERT_NODE));
- { svn_revnum_t rev = pibb->changed_rev;
SVN_ERR(svn_sqlite__bindf(stmt_node, "isisisr"
"tstr" /* 8 - 11 */
"isnnnnns", /* 12 - 19 */
@@ -772,12 +852,11 @@ insert_base_node(void *baton, svn_sqlite
(pibb->kind == svn_wc__db_kind_dir) ? /* 9 */
svn_depth_to_word(pibb->depth) : NULL,
kind_map, pibb->kind, /* 10 */
- rev, /* 11 */
+ pibb->changed_rev, /* 11 */
pibb->changed_date, /* 12 */
pibb->changed_author, /* 13 */
(pibb->kind == svn_wc__db_kind_symlink) ?
pibb->target : NULL)); /* 19 */
- }
if (pibb->kind == svn_wc__db_kind_file) {
SVN_ERR(svn_sqlite__bind_checksum(stmt_node, 14, pibb->checksum,
@@ -955,7 +1034,9 @@ insert_working_node(void *baton,
{
const insert_working_baton_t *piwb = baton;
const char *parent_relpath;
+#ifndef SVN_WC__NODES_ONLY
svn_sqlite__stmt_t *stmt;
+#endif
#ifdef SVN_WC__NODES
svn_sqlite__stmt_t *stmt_node;
apr_int64_t op_depth;
@@ -1376,15 +1457,34 @@ which_trees_exist(svn_boolean_t *base_ex
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
*base_exists = FALSE;
*working_exists = FALSE;
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_DETERMINE_TREE_FOR_RECORDING));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+ STMT_DETERMINE_TREE_FOR_RECORDING_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
+
if (have_row)
{
int value = svn_sqlite__column_int(stmt, 0);
@@ -1932,18 +2032,18 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
}
-svn_error_t *
-svn_wc__db_base_add_absent_node(svn_wc__db_t *db,
- const char *local_abspath,
- const char *repos_relpath,
- const char *repos_root_url,
- const char *repos_uuid,
- svn_revnum_t revision,
- svn_wc__db_kind_t kind,
- svn_wc__db_status_t status,
- const svn_skel_t *conflict,
- const svn_skel_t *work_items,
- apr_pool_t *scratch_pool)
+static svn_error_t *
+add_absent_excluded_not_present_node(svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *repos_relpath,
+ const char *repos_root_url,
+ const char *repos_uuid,
+ svn_revnum_t revision,
+ svn_wc__db_kind_t kind,
+ svn_wc__db_status_t status,
+ const svn_skel_t *conflict,
+ const svn_skel_t *work_items,
+ apr_pool_t *scratch_pool)
{
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
@@ -2002,6 +2102,46 @@ svn_wc__db_base_add_absent_node(svn_wc__
svn_error_t *
+svn_wc__db_base_add_absent_node(svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *repos_relpath,
+ const char *repos_root_url,
+ const char *repos_uuid,
+ svn_revnum_t revision,
+ svn_wc__db_kind_t kind,
+ svn_wc__db_status_t status,
+ const svn_skel_t *conflict,
+ const svn_skel_t *work_items,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR_ASSERT(status == svn_wc__db_status_absent
+ || status == svn_wc__db_status_excluded);
+
+ return add_absent_excluded_not_present_node(
+ db, local_abspath, repos_relpath, repos_root_url, repos_uuid, revision,
+ kind, status, conflict, work_items, scratch_pool);
+}
+
+
+svn_error_t *
+svn_wc__db_base_add_not_present_node(svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *repos_relpath,
+ const char *repos_root_url,
+ const char *repos_uuid,
+ svn_revnum_t revision,
+ svn_wc__db_kind_t kind,
+ const svn_skel_t *conflict,
+ const svn_skel_t *work_items,
+ apr_pool_t *scratch_pool)
+{
+ return add_absent_excluded_not_present_node(
+ db, local_abspath, repos_relpath, repos_root_url, repos_uuid, revision,
+ kind, svn_wc__db_status_not_present, conflict, work_items, scratch_pool);
+}
+
+
+svn_error_t *
svn_wc__db_base_remove(svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
@@ -2062,10 +2202,8 @@ svn_wc__db_base_get_info(svn_wc__db_stat
{
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
-#ifndef SVN_WC__NODES_ONLY
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
-#endif
#ifdef SVN_WC__NODES
svn_sqlite__stmt_t *stmt_nodes;
svn_boolean_t have_node_row;
@@ -2095,10 +2233,17 @@ svn_wc__db_base_get_info(svn_wc__db_stat
pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_node_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(assert_base_rows_match(have_row, have_node_row, stmt, stmt_nodes,
local_relpath, scratch_pool));
+#else
+ /* Lets assume the two queries return compatible data */
+ have_row = have_node_row;
+ stmt = stmt_nodes;
#endif
+#endif /* SVN_WC__NODES */
+
if (have_row)
{
svn_wc__db_kind_t node_kind = svn_sqlite__column_token(stmt, 3,
@@ -2229,8 +2374,10 @@ svn_wc__db_base_get_info(svn_wc__db_stat
}
#ifdef SVN_WC__NODES
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__reset(stmt_nodes));
#endif
+#endif
/* Note: given the composition, no need to wrap for tracing. */
return svn_error_compose_create(err, svn_sqlite__reset(stmt));
@@ -2362,10 +2509,29 @@ svn_wc__db_base_get_props(apr_hash_t **p
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
svn_error_t *err;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_node;
+ svn_boolean_t have_node_row;
+#endif
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
STMT_SELECT_BASE_PROPS, scratch_pool));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(get_statement_for_path(&stmt_node, db, local_abspath,
+ STMT_SELECT_BASE_PROPS_1, scratch_pool));
+ SVN_ERR(svn_sqlite__step(&have_node_row, stmt_node));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(have_row == have_node_row);
+ SVN_ERR(assert_blob_columns_equal(stmt, stmt_node, 0, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_node));
+#else
+ stmt = stmt_node;
+ have_row = have_node_row;
+#endif
+#endif
if (!have_row)
{
err = svn_sqlite__reset(stmt);
@@ -4864,6 +5030,12 @@ svn_wc__db_read_info(svn_wc__db_status_t
svn_boolean_t local_have_base;
svn_boolean_t local_have_work;
svn_boolean_t have_act;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes_base;
+ svn_sqlite__stmt_t *stmt_nodes_work;
+ svn_boolean_t local_have_nodes_base;
+ svn_boolean_t local_have_nodes_work;
+#endif
svn_error_t *err = NULL;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -4897,6 +5069,39 @@ svn_wc__db_read_info(svn_wc__db_status_t
pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_base, pdh->wcroot->sdb,
+ lock ? STMT_SELECT_BASE_NODE_WITH_LOCK_1
+ : STMT_SELECT_BASE_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes_base, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&local_have_nodes_base, stmt_nodes_base));
+
+ /* Possible optimisation: if we didn't select op_depth > 0 then this
+ would give us the base node when there is no working node. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_work, pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes_work, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&local_have_nodes_work, stmt_nodes_work));
+
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_base_rows_match(*have_base, local_have_nodes_base,
+ stmt_base, stmt_nodes_base,
+ local_relpath, scratch_pool));
+ SVN_ERR(assert_working_rows_match(*have_work, local_have_nodes_work,
+ stmt_work, stmt_nodes_work,
+ local_relpath, scratch_pool));
+#else
+ /* Lets assume the queries return compatible data */
+ *have_base = local_have_nodes_base;
+ *have_work = local_have_nodes_work;
+ stmt_base = stmt_nodes_base;
+ stmt_work = stmt_nodes_work;
+#endif
+
+#endif /* SVN_WC__NODES */
+
if (*have_base || *have_work)
{
svn_wc__db_kind_t node_kind;
@@ -5197,6 +5402,13 @@ svn_wc__db_read_info(svn_wc__db_status_t
scratch_pool));
}
+#ifdef SVN_WC__NODES
+#ifndef SVN_WC__NODES_ONLY
+ err = svn_error_compose_create(err, svn_sqlite__reset(stmt_nodes_base));
+ err = svn_error_compose_create(err, svn_sqlite__reset(stmt_nodes_work));
+#endif
+#endif
+
err = svn_error_compose_create(err, svn_sqlite__reset(stmt_base));
err = svn_error_compose_create(err, svn_sqlite__reset(stmt_work));
SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_act)));
@@ -5298,10 +5510,34 @@ svn_wc__db_read_pristine_props(apr_hash_
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_node;
+ svn_boolean_t have_node_row;
+#endif
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
STMT_SELECT_WORKING_PROPS, scratch_pool));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+ SVN_ERR(get_statement_for_path(&stmt_node, db, local_abspath,
+ STMT_SELECT_WORKING_PROPS_1, scratch_pool));
+ SVN_ERR(svn_sqlite__step(&have_node_row, stmt_node));
+
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(have_row == have_node_row);
+#if 0
+ /* Disabled for now as base-deleted don't match */
+ SVN_ERR(assert_blob_columns_equal(stmt, stmt_node, 0, scratch_pool));
+#endif
+ SVN_ERR(svn_sqlite__reset(stmt_node));
+#else
+ stmt = stmt_node;
+ have_row = have_node_row;
+#endif
+#endif
/* If there is a WORKING row, then examine its status:
@@ -7348,58 +7584,6 @@ svn_wc__db_temp_borrow_sdb(svn_sqlite__d
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_wc__db_temp_is_dir_deleted(svn_boolean_t *not_present,
- svn_revnum_t *base_revision,
- svn_wc__db_t *db,
- const char *local_dir_abspath,
- apr_pool_t *scratch_pool)
-{
- const char *parent_abspath;
- const char *base_name;
- svn_wc__db_pdh_t *pdh;
- const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
-
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_dir_abspath));
- SVN_ERR_ASSERT(not_present != NULL);
- SVN_ERR_ASSERT(base_revision != NULL);
-
- svn_dirent_split(&parent_abspath, &base_name, local_dir_abspath,
- scratch_pool);
-
- /* The parent should be a working copy if this function is called.
- Basically, the child is in an "added" state, which is not possible
- for a working copy root. */
- SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
- parent_abspath, svn_sqlite__mode_readonly,
- scratch_pool, scratch_pool));
- VERIFY_USABLE_PDH(pdh);
-
- /* Build the local_relpath for the requested directory. */
- local_relpath = svn_dirent_join(local_relpath, base_name, scratch_pool);
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_SELECT_PARENT_STUB_INFO));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
-
- /* There MAY be a BASE_NODE row in the parent directory. It is entirely
- possible the parent only has WORKING_NODE rows. If there is no BASE_NODE,
- then we certainly aren't looking at a 'not-present' row. */
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
- *not_present = have_row && svn_sqlite__column_int(stmt, 0);
- if (*not_present)
- {
- *base_revision = svn_sqlite__column_revnum(stmt, 1);
- }
- /* else don't touch *BASE_REVISION. */
-
- return svn_error_return(svn_sqlite__reset(stmt));
-}
-
svn_error_t *
svn_wc__db_read_conflict_victims(const apr_array_header_t **victims,
svn_wc__db_t *db,
@@ -8190,7 +8374,11 @@ svn_wc__db_temp_op_set_base_incomplete(s
SVN_ERR(svn_sqlite__bind_text(stmt, 3, incomplete ? "incomplete" : "normal"));
SVN_ERR(svn_sqlite__update(&affected_node_rows, stmt));
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR_ASSERT(affected_rows == affected_node_rows);
+#else
+ affected_rows = affected_node_rows;
+#endif
#endif
if (affected_rows > 0)
@@ -8495,7 +8683,8 @@ make_copy_txn(void *baton,
SVN_ERR(svn_sqlite__bindf(stmt, "isi",
mcb->pdh->wcroot->wc_id,
mcb->local_relpath,
- (*mcb->local_relpath == '\0') ? 1 : 2));
+ (*mcb->local_relpath == '\0'
+ ? (apr_int64_t)1 : (apr_int64_t)2)));
SVN_ERR(svn_sqlite__step_done(stmt));
#endif
@@ -8525,7 +8714,8 @@ make_copy_txn(void *baton,
SVN_ERR(svn_sqlite__bindf(stmt, "isi",
mcb->pdh->wcroot->wc_id,
mcb->local_relpath,
- (*mcb->local_relpath == '\0') ? 1 : 2));
+ (*mcb->local_relpath == '\0'
+ ? (apr_int64_t)1 : (apr_int64_t)2)));
SVN_ERR(svn_sqlite__step_done(stmt));
#endif
@@ -8687,6 +8877,10 @@ svn_wc__db_temp_elide_copyfrom(svn_wc__d
const char *local_relpath;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_node;
+ svn_boolean_t have_node_row;
+#endif
apr_int64_t original_repos_id;
const char *original_repos_relpath;
svn_revnum_t original_revision;
@@ -8706,10 +8900,29 @@ svn_wc__db_temp_elide_copyfrom(svn_wc__d
/* Examine the current WORKING_NODE row's copyfrom information. If there
is no WORKING node, then simply exit. */
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_node, pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_node, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_node_row, stmt_node));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_working_rows_match(have_row, have_node_row, stmt, stmt_node,
+ local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_node));
+#else
+ stmt = stmt_node;
+ have_row = have_node_row;
+#endif
+#endif
+
if (!have_row)
return svn_error_return(svn_sqlite__reset(stmt));
@@ -8759,10 +8972,22 @@ svn_wc__db_temp_elide_copyfrom(svn_wc__d
/* The child's copyfrom information is derivable from the parent.
The data should be reset to null, indicating the derivation. */
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_UPDATE_COPYFROM_TO_INHERIT));
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__update(NULL, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+ /* Should probably use the op_depth from query above and simplify this
+ query. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt_node, pdh->wcroot->sdb,
+ STMT_UPDATE_COPYFROM_TO_INHERIT_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_node, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__update(NULL, stmt_node));
+#endif
return SVN_NO_ERROR;
}
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h Tue Sep 21 14:14:12 2010
@@ -618,7 +618,6 @@ svn_wc__db_base_add_symlink(svn_wc__db_t
svn_wc__db_status_absent
svn_wc__db_status_excluded
- svn_wc__db_status_not_present
If CONFLICT is not NULL, then it describes a conflict for this node. The
node will be record as conflicted (in ACTUAL).
@@ -642,6 +641,36 @@ svn_wc__db_base_add_absent_node(svn_wc__
apr_pool_t *scratch_pool);
+/* Create a node in the BASE tree that is present in name only.
+
+ The new node will be located at LOCAL_ABSPATH, and correspond to the
+ repository node described by <REPOS_RELPATH, REPOS_ROOT_URL, REPOS_UUID>
+ at revision REVISION.
+
+ The node's kind is described by KIND, and the reason for its absence
+ is 'svn_wc__db_status_not_present'.
+
+ If CONFLICT is not NULL, then it describes a conflict for this node. The
+ node will be record as conflicted (in ACTUAL).
+
+ Any work items that are necessary as part of this node construction may
+ be passed in WORK_ITEMS.
+
+ All temporary allocations will be made in SCRATCH_POOL.
+*/
+svn_error_t *
+svn_wc__db_base_add_not_present_node(svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *repos_relpath,
+ const char *repos_root_url,
+ const char *repos_uuid,
+ svn_revnum_t revision,
+ svn_wc__db_kind_t kind,
+ const svn_skel_t *conflict,
+ const svn_skel_t *work_items,
+ apr_pool_t *scratch_pool);
+
+
/* Remove a node from the BASE tree.
The node to remove is indicated by LOCAL_ABSPATH from the local
@@ -2198,14 +2227,6 @@ svn_wc__db_temp_forget_directory(svn_wc_
const char *local_dir_abspath,
apr_pool_t *scratch_pool);
-
-svn_error_t *
-svn_wc__db_temp_is_dir_deleted(svn_boolean_t *not_present,
- svn_revnum_t *base_revision,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *scratch_pool);
-
/* Removes all references of LOCAL_ABSPATH from its working copy
using DB. */
svn_error_t *
Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c Tue Sep 21 14:14:12 2010
@@ -687,16 +687,15 @@ run_base_remove(svn_wc__db_t *db,
if (keep_not_present)
{
- SVN_ERR(svn_wc__db_base_add_absent_node(db, local_abspath,
- repos_relpath,
- repos_root_url,
- repos_uuid,
- revision,
- kind,
- svn_wc__db_status_not_present,
- NULL,
- NULL,
- scratch_pool));
+ SVN_ERR(svn_wc__db_base_add_not_present_node(db, local_abspath,
+ repos_relpath,
+ repos_root_url,
+ repos_uuid,
+ revision,
+ kind,
+ NULL,
+ NULL,
+ scratch_pool));
}
return SVN_NO_ERROR;
@@ -793,11 +792,10 @@ run_deletion_postcommit(svn_wc__db_t *db
lie; therefore, it must remember the file as being
'deleted' for a while. Create a new, uninteresting
ghost entry: */
- SVN_ERR(svn_wc__db_base_add_absent_node(
+ SVN_ERR(svn_wc__db_base_add_not_present_node(
db, local_abspath,
repos_relpath, repos_root_url, repos_uuid,
new_revision, kind,
- svn_wc__db_status_not_present,
NULL, NULL,
scratch_pool));
}
Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h Tue Sep 21 14:14:12 2010
@@ -645,12 +645,13 @@ dav_svn__get_deleted_rev_report(const da
/*** posts/ ***/
/* The list of Subversion's custom POSTs. */
-/* ### should move these report names to a public header to share with
- ### the client (and third parties). */
+/* ### TODO: Populate this list and transmit its contents in the
+ ### OPTIONS response.
static const char * dav_svn__posts_list[] = {
"create-txn",
NULL
};
+*/
/* The various POST handlers, defined in posts/, and used by repos.c. */
dav_error *
Modified: subversion/branches/atomic-revprop/subversion/svn/upgrade-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svn/upgrade-cmd.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svn/upgrade-cmd.c (original)
+++ subversion/branches/atomic-revprop/subversion/svn/upgrade-cmd.c Tue Sep 21 14:14:12 2010
@@ -31,6 +31,7 @@
#include "svn_client.h"
#include "svn_error_codes.h"
#include "svn_error.h"
+#include "svn_path.h"
#include "cl.h"
#include "svn_private_config.h"
@@ -59,6 +60,19 @@ svn_cl__upgrade(apr_getopt_t *os,
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
+ /* Don't even attempt to modify the working copy if any of the
+ * targets look like URLs. URLs are invalid input. */
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ if (svn_path_is_url(target))
+ return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
+ NULL,
+ _("'%s' is not a local path"),
+ target));
+ }
+
iterpool = svn_pool_create(scratch_pool);
for (i = 0; i < targets->nelts; i++)
{
Modified: subversion/branches/atomic-revprop/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svnrdump/dump_editor.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/atomic-revprop/subversion/svnrdump/dump_editor.c Tue Sep 21 14:14:12 2010
@@ -33,6 +33,12 @@
#define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))
+#ifdef SVN_DEBUG
+#define LDR_DBG(x) SVN_DBG(x)
+#else
+#define LDR_DBG(x) while(0)
+#endif
+
/* The baton used by the dump editor. */
struct dump_edit_baton {
/* The output stream we write the dumpfile to */
@@ -113,7 +119,7 @@ make_dir_baton(const char *path,
new_db->copyfrom_rev = copyfrom_rev;
new_db->added = added;
new_db->written_out = FALSE;
- new_db->deleted_entries = apr_hash_make(pool);
+ new_db->deleted_entries = apr_hash_make(eb->pool);
return new_db;
}
@@ -197,10 +203,10 @@ dump_node(struct dump_edit_baton *eb,
apr_pool_t *pool)
{
/* Remove leading slashes from path and copyfrom_path */
- if (path && strcmp(path, "/"))
+ if (path)
path = ((*path == '/') ? path + 1 : path);
- if (copyfrom_path && strcmp(copyfrom_path, "/"))
+ if (copyfrom_path)
copyfrom_path = ((*copyfrom_path == '/') ?
copyfrom_path + 1 : copyfrom_path);
@@ -315,6 +321,7 @@ open_root(void *edit_baton,
struct dump_edit_baton *eb = edit_baton;
/* Allocate a special pool for the edit_baton to avoid pool
lifetime issues */
+
eb->pool = svn_pool_create(pool);
eb->props = apr_hash_make(eb->pool);
eb->deleted_props = apr_hash_make(eb->pool);
@@ -322,6 +329,8 @@ open_root(void *edit_baton,
*root_baton = make_dir_baton(NULL, NULL, SVN_INVALID_REVNUM,
edit_baton, NULL, FALSE, pool);
+ LDR_DBG(("open_root %p\n", *root_baton));
+
return SVN_NO_ERROR;
}
@@ -332,14 +341,15 @@ delete_entry(const char *path,
apr_pool_t *pool)
{
struct dir_baton *pb = parent_baton;
- const char *mypath = apr_pstrdup(pool, path);
+
+ LDR_DBG(("delete_entry %s\n", path));
/* Some pending properties to dump? */
SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
/* Add this path to the deleted_entries of the parent directory
baton. */
- apr_hash_set(pb->deleted_entries, mypath, APR_HASH_KEY_STRING, pb);
+ apr_hash_set(pb->deleted_entries, path, APR_HASH_KEY_STRING, pb);
return SVN_NO_ERROR;
}
@@ -358,6 +368,8 @@ add_directory(const char *path,
= make_dir_baton(path, copyfrom_path, copyfrom_rev, pb->eb, pb, TRUE, pool);
svn_boolean_t is_copy;
+ LDR_DBG(("add_directory %s\n", path));
+
/* Some pending properties to dump? */
SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
@@ -398,6 +410,8 @@ open_directory(const char *path,
const char *copyfrom_path = NULL;
svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
+ LDR_DBG(("open_directory %s\n", path));
+
/* Some pending properties to dump? */
SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
@@ -423,14 +437,19 @@ close_directory(void *dir_baton,
{
struct dir_baton *db = dir_baton;
struct dump_edit_baton *eb = db->eb;
+ apr_pool_t *iterpool;
apr_hash_index_t *hi;
- apr_pool_t *iterpool = svn_pool_create(pool);
+
+ LDR_DBG(("close_directory %p\n", dir_baton));
+
+ /* Create a pool just for iterations to allocate a loop variable */
+ iterpool = svn_pool_create(pool);
/* Some pending properties to dump? */
SVN_ERR(dump_props(eb, &(eb->dump_props_pending), TRUE, pool));
- /* Dump the directory entries */
- for (hi = apr_hash_first(pool, db->deleted_entries); hi;
+ /* Dump the deleted directory entries */
+ for (hi = apr_hash_first(iterpool, db->deleted_entries); hi;
hi = apr_hash_next(hi))
{
const void *key;
@@ -438,12 +457,11 @@ close_directory(void *dir_baton,
apr_hash_this(hi, &key, NULL, NULL);
path = key;
- svn_pool_clear(iterpool);
-
SVN_ERR(dump_node(db->eb, path, svn_node_unknown, svn_node_action_delete,
- FALSE, NULL, SVN_INVALID_REVNUM, iterpool));
+ FALSE, NULL, SVN_INVALID_REVNUM, pool));
}
+ svn_hash__clear(db->deleted_entries, pool);
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
@@ -460,6 +478,8 @@ add_file(const char *path,
void *val;
svn_boolean_t is_copy;
+ LDR_DBG(("add_file %s\n", path));
+
/* Some pending properties to dump? */
SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
@@ -500,6 +520,8 @@ open_file(const char *path,
const char *copyfrom_path = NULL;
svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
+ LDR_DBG(("open_file %s\n", path));
+
/* Some pending properties to dump? */
SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
@@ -530,6 +552,8 @@ change_dir_prop(void *parent_baton,
{
struct dir_baton *db = parent_baton;
+ LDR_DBG(("change_dir_prop %p\n", parent_baton));
+
if (svn_property_kind(NULL, name) != svn_prop_regular_kind)
return SVN_NO_ERROR;
@@ -566,6 +590,8 @@ change_file_prop(void *file_baton,
{
struct dump_edit_baton *eb = file_baton;
+ LDR_DBG(("change_file_prop %p\n", file_baton));
+
if (svn_property_kind(NULL, name) != svn_prop_regular_kind)
return SVN_NO_ERROR;
@@ -620,6 +646,8 @@ apply_textdelta(void *file_baton, const
hb->pool = handler_pool;
hb->eb = eb;
+ LDR_DBG(("apply_textdelta %p\n", file_baton));
+
/* Use a temporary file to measure the text-content-length */
SVN_ERR(svn_stream_open_unique(&(hb->delta_filestream), &hb->delta_abspath,
NULL, svn_io_file_del_none, hb->pool,
@@ -650,6 +678,8 @@ close_file(void *file_baton,
svn_stream_t *delta_filestream;
apr_finfo_t *info = apr_pcalloc(pool, sizeof(apr_finfo_t));
+ LDR_DBG(("close_file %p\n", file_baton));
+
/* Some pending properties to dump? */
SVN_ERR(dump_props(eb, &(eb->dump_props_pending), FALSE, pool));
@@ -737,6 +767,7 @@ static svn_error_t *
close_edit(void *edit_baton, apr_pool_t *pool)
{
struct dump_edit_baton *eb = edit_baton;
+ LDR_DBG(("close_edit\n"));
svn_pool_destroy(eb->pool);
return SVN_NO_ERROR;
Modified: subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c Tue Sep 21 14:14:12 2010
@@ -30,9 +30,15 @@
#include "svn_path.h"
#include "svn_ra.h"
#include "svn_io.h"
+#include "svn_private_config.h"
+
+#include <apr_network_io.h>
#include "load_editor.h"
+#define SVNRDUMP_PROP_LOCK SVN_PROP_PREFIX "rdump-lock"
+#define LOCK_RETRIES 10
+
#ifdef SVN_DEBUG
#define LDR_DBG(x) SVN_DBG(x)
#else
@@ -50,6 +56,66 @@ commit_callback(const svn_commit_info_t
return SVN_NO_ERROR;
}
+/* Acquire a lock (of sorts) on the repository associated with the
+ * given RA SESSION. This lock is just a revprop change attempt in a
+ * time-delay loop. This function is duplicated by svnsync in main.c.
+ *
+ * ### TODO: Make this function more generic and
+ * expose it through a header for use by other Subversion
+ * applications to avoid duplication.
+ */
+static svn_error_t *
+get_lock(svn_ra_session_t *session, apr_pool_t *pool)
+{
+ char hostname_str[APRMAXHOSTLEN + 1] = { 0 };
+ svn_string_t *mylocktoken, *reposlocktoken;
+ apr_status_t apr_err;
+ apr_pool_t *subpool;
+ int i;
+
+ apr_err = apr_gethostname(hostname_str, sizeof(hostname_str), pool);
+ if (apr_err)
+ return svn_error_wrap_apr(apr_err, _("Can't get local hostname"));
+
+ mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,
+ svn_uuid_generate(pool));
+
+ subpool = svn_pool_create(pool);
+
+ for (i = 0; i < LOCK_RETRIES; ++i)
+ {
+ svn_pool_clear(subpool);
+
+ SVN_ERR(svn_ra_rev_prop(session, 0, SVNRDUMP_PROP_LOCK, &reposlocktoken,
+ subpool));
+
+ if (reposlocktoken)
+ {
+ /* Did we get it? If so, we're done, otherwise we sleep. */
+ if (strcmp(reposlocktoken->data, mylocktoken->data) == 0)
+ return SVN_NO_ERROR;
+ else
+ {
+ SVN_ERR(svn_cmdline_printf
+ (pool, _("Failed to get lock on destination "
+ "repos, currently held by '%s'\n"),
+ reposlocktoken->data));
+
+ apr_sleep(apr_time_from_sec(1));
+ }
+ }
+ else if (i < LOCK_RETRIES - 1)
+ {
+ /* Except in the very last iteration, try to set the lock. */
+ SVN_ERR(svn_ra_change_rev_prop(session, 0, SVNRDUMP_PROP_LOCK,
+ mylocktoken, subpool));
+ }
+ }
+
+ return svn_error_createf(APR_EINVAL, NULL,
+ _("Couldn't get lock on destination repos "
+ "after %d attempts"), i);
+}
static svn_error_t *
new_revision_record(void **revision_baton,
@@ -539,13 +605,11 @@ drive_dumpstream_loader(svn_stream_t *st
struct parse_baton *pb;
pb = parse_baton;
- /* ### TODO: Figure out if we're allowed to set revprops before
- ### we're too late and mess up the repository. svnsync uses some
- ### sort of locking mechanism. */
-
+ SVN_ERR(get_lock(session, pool));
SVN_ERR(svn_ra_get_repos_root2(session, &(pb->root_url), pool));
SVN_ERR(svn_repos_parse_dumpstream2(stream, parser, parse_baton,
NULL, NULL, pool));
+ SVN_ERR(svn_ra_change_rev_prop(session, 0, SVNRDUMP_PROP_LOCK, NULL, pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/atomic-revprop/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svnserve/serve.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svnserve/serve.c (original)
+++ subversion/branches/atomic-revprop/subversion/svnserve/serve.c Tue Sep 21 14:14:12 2010
@@ -1505,6 +1505,14 @@ static svn_error_t *get_dir(svn_ra_svn_c
svn_pool_clear(subpool);
file_path = svn_uri_join(full_path, name, subpool);
+
+ if (! lookup_access(subpool, b, conn, svn_authz_read,
+ file_path, FALSE))
+ {
+ apr_hash_set(entries, name, APR_HASH_KEY_STRING, NULL);
+ continue;
+ }
+
entry = apr_pcalloc(pool, sizeof(*entry));
if (dirent_fields & SVN_DIRENT_KIND)
Modified: subversion/branches/atomic-revprop/subversion/svnsync/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svnsync/main.c?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svnsync/main.c (original)
+++ subversion/branches/atomic-revprop/subversion/svnsync/main.c Tue Sep 21 14:14:12 2010
@@ -310,7 +310,13 @@ maybe_unlock(svn_ra_session_t *session,
}
/* Acquire a lock (of sorts) on the repository associated with the
- * given RA SESSION.
+ * given RA SESSION. This lock is just a revprop change attempt in a
+ * time-delay loop. This function is duplicated by svnrdump in
+ * load_editor.c.
+ *
+ * ### TODO: Make this function more generic and
+ * expose it through a header for use by other Subversion
+ * applications to avoid duplication.
*/
static svn_error_t *
get_lock(const svn_string_t **lock_string_p,
Modified: subversion/branches/atomic-revprop/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/tests/cmdline/authz_tests.py?rev=999427&r1=999426&r2=999427&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/atomic-revprop/subversion/tests/cmdline/authz_tests.py Tue Sep 21 14:14:12 2010
@@ -1091,9 +1091,8 @@ test_list = [ None,
Skip(wc_wc_copy, svntest.main.is_ra_type_file),
Skip(wc_wc_copy_revert,
svntest.main.is_ra_type_file),
- XFail(Skip(authz_recursive_ls,
- svntest.main.is_ra_type_file),
- svntest.main.is_ra_type_svn),
+ Skip(authz_recursive_ls,
+ svntest.main.is_ra_type_file),
]
if __name__ == '__main__':