You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/11/04 21:48:30 UTC
svn commit: r1031230 [10/21] - in /subversion/branches/py-tests-as-modules:
./ build/ build/ac-macros/ build/win32/ contrib/client-side/ notes/
notes/http-and-webdav/ notes/wc-ng/ subversion/bindings/ctypes-python/csvn/
subversion/bindings/javahl/nativ...
Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/update_editor.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/update_editor.c Thu Nov 4 20:48:21 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
@@ -1097,29 +1091,6 @@ window_handler(svn_txdelta_window_t *win
}
-/* Prepare directory for dir_baton DB for updating or checking out.
- * Give it depth DEPTH.
- *
- * If the path already exists, but is not a working copy for
- * ANCESTOR_URL and ANCESTOR_REVISION, then an error will be returned.
- */
-static svn_error_t *
-prep_directory(struct dir_baton *db,
- const char *ancestor_url,
- svn_revnum_t ancestor_revision,
- apr_pool_t *pool)
-{
- const char *dir_abspath;
-
- dir_abspath = db->local_abspath;
-
- /* Make sure the directory exists. */
- SVN_ERR(svn_wc__ensure_directory(dir_abspath, pool));
-
- return SVN_NO_ERROR;
-}
-
-
/* Find the last-change info within ENTRY_PROPS, and return then in the
CHANGED_* parameters. Each parameter will be initialized to its "none"
value, and will contain the relavent info if found.
@@ -1556,7 +1527,8 @@ create_tree_conflict(svn_wc_conflict_des
* calling this function. Do that on the caller's side. */
right_repos_relpath = eb->switch_relpath;
right_repos_relpath = apr_pstrcat(result_pool, right_repos_relpath,
- "_THIS_IS_INCOMPLETE", NULL);
+ "_THIS_IS_INCOMPLETE",
+ (char *)NULL);
}
}
else
@@ -1969,7 +1941,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,
@@ -2123,7 +2094,7 @@ delete_entry(const char *path,
apr_pool_t *pool)
{
struct dir_baton *pb = parent_baton;
- const char *base = svn_relpath_basename(path, pool);
+ const char *base = svn_relpath_basename(path, NULL);
const char *local_abspath;
const char *their_relpath;
@@ -2153,7 +2124,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 +2139,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 +2402,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));
@@ -2517,17 +2450,12 @@ add_directory(const char *path,
db->ambient_depth,
pool));
- SVN_ERR(prep_directory(db,
- svn_path_url_add_component2(eb->repos_root,
- db->new_relpath, pool),
- *(eb->target_revision),
- db->pool));
+ SVN_ERR(svn_wc__ensure_directory(db->local_abspath, pool));
/* If PATH is within a locally deleted tree then make it also
- scheduled for deletion. We must do this after the call to
- prep_directory() otherwise the administrative area for DB->PATH
- is not present, nor is there an entry for DB->PATH in DB->PATH's
- entries. */
+ scheduled for deletion. We should do this at the same time as
+ setting the dir incomplete otherwise the db is temporarily
+ invalid. */
if (pb->in_deleted_and_tree_conflicted_subtree)
{
SVN_ERR(svn_wc__db_temp_op_delete(eb->db, db->local_abspath, pool));
@@ -2969,22 +2897,10 @@ close_directory(void *dir_baton,
item to write out an old-style props file. */
if (new_base_props != NULL)
{
- apr_array_header_t *prop_diffs;
-
SVN_ERR_ASSERT(new_actual_props != NULL);
- /* If the ACTUAL props are the same as the BASE props, then we
- should "write" a NULL. This will remove the props from the
- ACTUAL_NODE row, and remove the old-style props file, indicating
- "no change". */
- props = new_actual_props;
- SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
- pool));
- if (prop_diffs->nelts == 0)
- props = NULL;
-
SVN_ERR(svn_wc__db_op_set_props(eb->db, db->local_abspath,
- props,
+ new_actual_props,
NULL /* conflict */,
NULL /* work_items */,
pool));
@@ -3113,477 +3029,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 +3050,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 +3280,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 +3314,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;
@@ -4833,7 +4264,6 @@ close_file(void *file_baton,
* a text conflict. So flag a tree conflict here. */
if (fb->adding_file && fb->add_existed)
{
- int i;
svn_boolean_t local_is_link = FALSE;
svn_boolean_t incoming_is_link = FALSE;
@@ -4852,6 +4282,8 @@ close_file(void *file_baton,
}
else
{
+ int i;
+
for (i = 0; i < regular_props->nelts; ++i)
{
const svn_prop_t *prop = &APR_ARRAY_IDX(regular_props, i,
@@ -4917,32 +4349,31 @@ close_file(void *file_baton,
/* We will ALWAYS have properties to save (after a not-dry-run merge). */
SVN_ERR_ASSERT(new_base_props != NULL && new_actual_props != NULL);
- /* Merge the text. This will queue some additional work. */
- SVN_ERR(merge_file(&all_work_items, &install_pristine, &install_from,
- &content_state, fb, new_text_base_sha1_checksum,
- pool, scratch_pool));
-
- if (install_pristine)
- {
- svn_boolean_t record_fileinfo;
-
- /* If we are installing from the pristine contents, then go ahead and
- record the fileinfo. That will be the "proper" values. Installing
- from some random file means the fileinfo does NOT correspond to
- the pristine (in which case, the fileinfo will be cleared for
- safety's sake). */
- record_fileinfo = install_from == NULL;
-
- SVN_ERR(svn_wc__wq_build_file_install(&work_item,
- eb->db,
- fb->local_abspath,
- install_from,
- eb->use_commit_times,
- record_fileinfo,
- pool, pool));
- all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
- }
+ /* Merge the text. This will queue some additional work. */
+ SVN_ERR(merge_file(&all_work_items, &install_pristine, &install_from,
+ &content_state, fb, new_text_base_sha1_checksum,
+ pool, scratch_pool));
+
+ if (install_pristine)
+ {
+ svn_boolean_t record_fileinfo;
+
+ /* If we are installing from the pristine contents, then go ahead and
+ record the fileinfo. That will be the "proper" values. Installing
+ from some random file means the fileinfo does NOT correspond to
+ the pristine (in which case, the fileinfo will be cleared for
+ safety's sake). */
+ record_fileinfo = install_from == NULL;
+ SVN_ERR(svn_wc__wq_build_file_install(&work_item,
+ eb->db,
+ fb->local_abspath,
+ install_from,
+ eb->use_commit_times,
+ record_fileinfo,
+ pool, pool));
+ all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
+ }
}
else
{
@@ -5097,7 +4528,8 @@ close_file(void *file_baton,
/* 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. */
+ that tree. We need to schedule this file for deletion. This
+ should happen at the same time as svn_wc__db_base_add_file. */
if (fb->dir_baton->in_deleted_and_tree_conflicted_subtree && fb->adding_file)
{
SVN_ERR(svn_wc__db_temp_op_delete(eb->db, fb->local_abspath, pool));
@@ -5115,23 +4547,10 @@ close_file(void *file_baton,
properties merge. */
if (! fb->adding_base_under_local_add)
{
- apr_hash_t *props;
- apr_array_header_t *prop_diffs;
-
SVN_ERR_ASSERT(new_actual_props != NULL);
- /* If the ACTUAL props are the same as the BASE props, then we
- should "write" a NULL. This will remove the props from the
- ACTUAL_NODE row, and remove the old-style props file, indicating
- "no change". */
- props = new_actual_props;
- SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
- pool));
- if (prop_diffs->nelts == 0)
- props = NULL;
-
SVN_ERR(svn_wc__db_op_set_props(eb->db, fb->local_abspath,
- props,
+ new_actual_props,
NULL /* conflict */,
NULL /* work_item */,
pool));
@@ -5336,7 +4755,7 @@ tweak_entries(svn_wc__db_t *db,
svn_wc__db_status_t status;
const char *child_repos_relpath = NULL;
- svn_boolean_t excluded;
+ svn_boolean_t excluded, is_file_external;
svn_pool_clear(iterpool);
@@ -5346,12 +4765,21 @@ tweak_entries(svn_wc__db_t *db,
child_basename, iterpool);
child_abspath = svn_dirent_join(dir_abspath, child_basename, iterpool);
+
+ /* Skip stuff we've already decided to exclude. */
excluded = (apr_hash_get(exclude_paths, child_abspath,
APR_HASH_KEY_STRING) != NULL);
-
if (excluded)
continue;
+ /* Skip stuff we've identified as file externals. (If we're
+ here, we were doing an update of a directory, not the actual
+ switch handling of a file external itself.) */
+ SVN_ERR(svn_wc__internal_is_file_external(&is_file_external, db,
+ child_abspath, iterpool));
+ if (is_file_external)
+ continue;
+
SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -5577,8 +5005,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 +5079,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 +5148,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 +5166,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 +5184,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 +5205,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 +5327,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;
@@ -6051,6 +5468,18 @@ svn_wc__strictly_is_wc_root(svn_boolean_
svn_error_t *
+svn_wc_get_wc_root(const char **wcroot_abspath,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool)
+{
+ return svn_wc__db_get_wcroot(wcroot_abspath, wc_ctx->db,
+ local_abspath, scratch_pool, result_pool);
+}
+
+
+svn_error_t *
svn_wc_get_actual_target2(const char **anchor,
const char **target,
svn_wc_context_t *wc_ctx,
@@ -6114,8 +5543,6 @@ svn_wc_add_repos_file4(svn_wc_context_t
svn_revnum_t copyfrom_rev,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
apr_pool_t *scratch_pool)
{
svn_wc__db_t *db = wc_ctx->db;
@@ -6131,7 +5558,6 @@ svn_wc_add_repos_file4(svn_wc_context_t
const char *original_root_url;
const char *original_repos_relpath;
const char *original_uuid;
- apr_hash_t *actual_props;
svn_revnum_t changed_rev;
apr_time_t changed_date;
const char *changed_author;
@@ -6253,25 +5679,6 @@ svn_wc_add_repos_file4(svn_wc_context_t
entry_props, pool, pool));
}
- /* Add some work items to install the properties. */
- {
- if (new_props == NULL)
- {
- actual_props = NULL;
- }
- else
- {
- apr_array_header_t *prop_diffs;
-
- SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, new_base_props,
- pool));
- if (prop_diffs->nelts == 0)
- actual_props = NULL;
- else
- actual_props = new_props;
- }
- }
-
/* Copy NEW_BASE_CONTENTS into a temporary file so our log can refer to
it, and set TMP_TEXT_BASE_ABSPATH to its path. Compute its
NEW_TEXT_BASE_MD5_CHECKSUM and NEW_TEXT_BASE_SHA1_CHECKSUM as we copy. */
@@ -6396,7 +5803,7 @@ svn_wc_add_repos_file4(svn_wc_context_t
/* ### if below fails, then the above db change would remain :-( */
SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
- actual_props,
+ new_props,
NULL /* conflict */,
all_work_items,
pool));
Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/upgrade.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/upgrade.c Thu Nov 4 20:48:21 2010
@@ -720,7 +720,7 @@ db_kind_from_node_kind(svn_node_kind_t n
static svn_error_t *
migrate_single_tree_conflict_data(svn_sqlite__db_t *sdb,
const char *tree_conflict_data,
- apr_uint64_t wc_id,
+ apr_int64_t wc_id,
const char *local_relpath,
apr_pool_t *scratch_pool)
{
@@ -847,7 +847,7 @@ migrate_tree_conflicts(svn_sqlite__db_t
SVN_ERR(svn_sqlite__step(&have_row, select_stmt));
while (have_row)
{
- apr_uint64_t wc_id;
+ apr_int64_t wc_id;
const char *local_relpath;
const char *tree_conflict_data;
@@ -987,21 +987,21 @@ migrate_node_props(const char *dir_abspa
apr_pstrcat(scratch_pool,
name,
SVN_WC__BASE_EXT,
- NULL),
+ (char *)NULL),
scratch_pool);
revert_abspath = svn_dirent_join(basedir_abspath,
apr_pstrcat(scratch_pool,
name,
SVN_WC__REVERT_EXT,
- NULL),
+ (char *)NULL),
scratch_pool);
working_abspath = svn_dirent_join(propsdir_abspath,
apr_pstrcat(scratch_pool,
name,
SVN_WC__WORK_EXT,
- NULL),
+ (char *)NULL),
scratch_pool);
}
@@ -1195,6 +1195,16 @@ bump_to_17(void *baton, svn_sqlite__db_t
return SVN_NO_ERROR;
}
+#if (SVN_WC__VERSION > 19)
+static svn_error_t *
+bump_to_20(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+ SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_NODES));
+ SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_20));
+ return SVN_NO_ERROR;
+}
+#endif
+
#if 0 /* ### no tree conflict migration yet */
@@ -1482,22 +1492,28 @@ svn_wc__upgrade_sdb(int *result_format,
*result_format = 18;
/* FALLTHROUGH */
-#if (SVN_WC__VERSION > 18)
case 18:
return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("The working copy '%s' is at format 18; "
"use 'tools/dev/wc-ng/bump-to-19.py' to "
"upgrade it"), wcroot_abspath);
+
+#if (SVN_WC__VERSION > 19)
+ case 19:
+ SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_20, &bb,
+ scratch_pool));
+ *result_format = 20;
+ /* FALLTHROUGH */
#endif
/* ### future bumps go here. */
#if 0
- case 98:
+ case XXX-1:
/* Revamp the recording of tree conflicts. */
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_XXX,
- (void *)wcroot_abspath,
+ SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_XXX, &bb,
scratch_pool));
- *result_format = 99;
+ *result_format = XXX;
+ /* FALLTHROUGH */
#endif
}
@@ -1691,6 +1707,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
scratch_pool);
pristine_to = svn_wc__adm_child(local_abspath, PRISTINE_STORAGE_RELPATH,
scratch_pool);
+ SVN_ERR(svn_wc__ensure_directory(pristine_from, scratch_pool));
SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
pristine_from, pristine_to,
scratch_pool, scratch_pool));
Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_wc/wc-metadata.sql?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_wc/wc-metadata.sql Thu Nov 4 20:48:21 2010
@@ -76,250 +76,9 @@ CREATE UNIQUE INDEX I_LOCAL_ABSPATH ON W
/* ------------------------------------------------------------------------- */
-/*
-The BASE_NODE table:
-
- BASE is what we get from the server. It is the *absolute* pristine copy.
- You need to use checkout, update, switch, or commit to alter your view of
- the repository.
-
- In the BASE tree, each node corresponds to a particular node-rev in the
- repository. It can be a mixed-revision tree. Each node holds either a
- copy of the node-rev as it exists in the repository (if presence ==
- 'normal'), or a place-holder (if presence == 'absent' or 'excluded' or
- 'not-present').
- [Quoted from wc_db.h]
-
-Overview of BASE_NODE columns:
-
- Indexing columns: (wc_id, local_relpath, parent_relpath)
-
- (presence)
-
- - The Node-Rev, Content and Last-Change column groups take one of the
- states shown in the table below, according to the 'presence':
-
- Has Has Has
- 'presence' Meaning Node-Rev? Content? Last-Change?
- ---------- ----------- ----------- -------- ------------
- normal => Present Yes Yes Yes
- incomplete => Incomplete Yes Partial No ### ?
- absent => Unauthz Yes No No
- excluded => Unwanted Yes No No
- not-present => Nonexistent No No No
-
- - If presence==incomplete, this node refers to an existing node-rev but
- its Content is not fully and correctly stored. In particular, if it
- is a directory, some rows that should represent its children may not
- exist or may be in the wrong state. This is intended to be a
- temporary state, e.g. during an update.
-
- - If presence==absent or ==excluded, this row refers to a node that
- exists in the repo, but the node is not stored in the WC.
-
- - If presence==not-present, this row indicates that its parent in the WC
- is a directory that, in its pristine state, would have a child of this
- name. However, this child was updated or switched to a node-revision
- that does not exist. Information about which node-revision it was
- updated or switched to is lost; only the fact that it is currently not
- present is remembered.
-
- - The order of precedence of the negative presence values is:
- 'excluded' if administratively excluded from the WC, else
- 'absent' if server doesn't authorize reading the path, else
- 'not-present' if it does not exist in repo.
-
- Node-Rev columns: (repos_id, repos_relpath, revnum)
-
- - The Node-Rev group points to the corresponding repository node-rev.
-
- - If not used (as specified by the 'presence' table above), the values
- are undefined.
- ### Perhaps we should set them to null to make it clearer.
-
- Content columns: (kind, properties, depth, target, checksum)
- ---- ---------- ----- ------ --------
- 'dir' Yes Yes null null
- 'symlink' Yes null Yes null
- 'file' Yes null null Yes
- 'unknown' null null null null
-
- - The Content columns take one of the states shown in the table above.
- If Content is present, a copy of the Node-Rev's content is stored
- locally according to one of the first three rows in the table above,
- otherwise kind==unknown and the other columns are null.
-
- - If kind==dir, the children are represented by the existence of other
- BASE_NODE rows. For each immediate child of 'repos_relpath'@'revnum'
- in the repo, subject to 'depth', a BASE_NODE row exists with its
- 'local_relpath' being this node's 'local_relpath' plus the child's
- basename. (Rows may also exist for additional children which are
- outside the scope of 'depth' or do not exist as children of this
- node-rev in the repository, including 'externals' and paths updated to
- a revision in which they do exist.) There is no distinction between
- depth==immediates and depth==infinity here.
-
- - If kind==symlink, the target path is contained in 'target'.
-
- - If kind==file, the content is contained in the Pristine Store,
- referenced by its SHA-1 checksum 'checksum'.
-
- Last-Change columns: (changed_rev, changed_date, changed_author)
-
- - Specifies the revision in which the content was last changed before
- Node-Rev, following copies and not counting the copy operation itself
- as a change.
-
- - Does not specify the revision in which this node first appeared at
- the repository path 'repos_relpath', which could be more recent than
- the last change of this node's content.
-
- - Includes a copy of the corresponding date and author rev-props.
-
- - If not used (as specified by the 'presence' table above), all null.
- ### Not checked; in practice these columns may have undefined values.
-
- Working file status: (translated_size, last_mod_time)
-
- - Present iff kind==file and node has no WORKING_NODE row, otherwise
- null. (If kind==file and node has a WORKING_NODE row, the info is
- recorded in that row). ### True?
-
- - Records the status of the working file on disk, for the purpose of
- detecting quickly whether that file has been modified.
-
- - Logically belongs to the ACTUAL_NODE table but is recorded in the
- BASE_NODE and WORKING_NODE tables instead to avoid the overhead of
- storing an ACTUAL_NODE row for each unmodified file.
-
- - Records the actual size and mod-time of the disk file at the time when
- its content was last determined to be logically unmodified relative to
- its base, taking account of keywords and EOL style.
-
- (dav_cache)
-
- - Content is opaque to libsvn_wc. ### ?
-
- - Lifetime is managed by the WC: values cleared to null at certain times.
- ### To be documented.
-
- (incomplete_children)
-
- - Obsolete, unused.
-
- (file_external)
-
- - ### To be obsoleted?
-*/
-
-CREATE TABLE BASE_NODE (
- /* specifies the location of this node in the local filesystem. wc_id
- implies an absolute path, and local_relpath is relative to that
- location (meaning it will be "" for the wcroot). */
- wc_id INTEGER NOT NULL REFERENCES WCROOT (id),
- local_relpath TEXT NOT NULL,
-
- /* The repository this node is part of, and the relative path (from its
- root) within revision "revnum" of that repository. These may be NULL,
- implying they should be derived from the parent and local_relpath.
- Non-NULL typically indicates a switched node.
-
- Note: they must both be NULL, or both non-NULL. */
- repos_id INTEGER REFERENCES REPOSITORY (id),
- repos_relpath TEXT,
-
- /* parent's local_relpath for aggregating children of a given parent.
- this will be "" if the parent is the wcroot. NULL if this is the
- wcroot node. */
- parent_relpath TEXT,
-
- /* Is this node "present" or has it been excluded for some reason?
- The "base-deleted" presence value is not allowed. */
- presence TEXT NOT NULL,
-
- /* The node kind: "file", "dir", or "symlink", or "unknown" if the node is
- not present. */
- kind TEXT NOT NULL,
-
- /* The revision number in which "repos_relpath" applies in "repos_id".
- this could be NULL for non-present nodes -- no info. */
- revnum INTEGER,
-
- /* If this node is a file, then the SHA-1 checksum of the pristine text. */
- checksum TEXT,
-
- /* The size in bytes of the working file when it had no local text
- modifications. This means the size of the text when translated from
- repository-normal format to working copy format with EOL style
- translated and keywords expanded according to the properties in the
- "properties" column of this row.
-
- NULL if this node is not a file or if the size has not (yet) been
- computed. */
- translated_size INTEGER,
-
- /* Information about the last change to this node. changed_rev must be
- not-null if this node has presence=="normal". changed_date and
- changed_author may be null if the corresponding revprops are missing.
-
- All three values are null for a not-present node. */
- changed_rev INTEGER,
- changed_date INTEGER, /* an APR date/time (usec since 1970) */
- changed_author TEXT,
-
- /* NULL depth means "default" (typically svn_depth_infinity) */
- depth TEXT,
-
- /* for kind==symlink, this specifies the target. */
- symlink_target TEXT,
-
- /* The mod-time of the working file when it was last determined to be
- logically unmodified relative to its base, taking account of keywords
- and EOL style.
-
- NULL if this node is not a file or if this info has not yet been
- determined.
- */
- /* ### Do we need this? We've currently got various mod time APIs
- ### internal to libsvn_wc, but those might be used in answering some
- ### question which is better answered some other way. */
- last_mod_time INTEGER, /* an APR date/time (usec since 1970) */
-
- /* serialized skel of this node's properties. NULL if we
- have no information about the properties (a non-present node). */
- properties BLOB,
-
- /* serialized skel of this node's dav-cache. could be NULL if the
- node does not have any dav-cache. */
- dav_cache BLOB,
-
- /* ### this column is removed in format 13. it will always be NULL. */
- incomplete_children INTEGER,
-
- /* The serialized file external information. */
- /* ### hack. hack. hack.
- ### This information is already stored in properties, but because the
- ### current working copy implementation is such a pain, we can't
- ### readily retrieve it, hence this temporary cache column.
- ### When it is removed, be sure to remove the extra column from
- ### the db-tests.
-
- ### Note: This is only here as a hack, and should *NOT* be added
- ### to any wc_db APIs. */
- file_external TEXT,
-
- PRIMARY KEY (wc_id, local_relpath)
- );
-
-CREATE INDEX I_PARENT ON BASE_NODE (wc_id, parent_relpath);
-
-
-/* ------------------------------------------------------------------------- */
-
/* The PRISTINE table keeps track of pristine texts. Each pristine text is
stored in a file which may be compressed. Each pristine text is
- referenced by any number of rows in the BASE_NODE and WORKING_NODE
- and ACTUAL_NODE tables.
+ referenced by any number of rows in the NODES and ACTUAL_NODE tables.
*/
CREATE TABLE PRISTINE (
/* The SHA-1 checksum of the pristine text. This is a unique key. The
@@ -337,7 +96,7 @@ CREATE TABLE PRISTINE (
size INTEGER,
/* ### this will probably go away, in favor of counting references
- ### that exist in BASE_NODE and WORKING_NODE. */
+ ### that exist in NODES. */
refcount INTEGER NOT NULL,
/* Alternative MD5 checksum used for communicating with older
@@ -349,173 +108,16 @@ CREATE TABLE PRISTINE (
/* ------------------------------------------------------------------------- */
-/* The WORKING_NODE table describes tree changes in the WC relative to the
- BASE_NODE table.
-
- The WORKING_NODE row for a given path exists iff a node at this path
- is itself one of:
-
- - deleted
- - moved away [1]
-
- and/or one of:
-
- - added
- - copied here [1]
- - moved here [1]
-
- or if this path is a child (or grandchild, etc.) under any such node.
- (### Exact meaning of "child" when mixed-revision, switched, etc.?)
-
- [1] The WC-NG "move" operation requires that both the source and
- destination paths are represented in the BASE_NODE and WORKING_NODE
- tables. The "copy" operation takes as its source a repository node,
- regardless whether that node is also represented in the WC.
- */
-CREATE TABLE WORKING_NODE (
- /* specifies the location of this node in the local filesystem */
- wc_id INTEGER NOT NULL REFERENCES WCROOT (id),
- local_relpath TEXT 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,
-
- /* 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,
-
- /* 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,
-
- /* The size in bytes of the working file when it had no local text
- modifications. This means the size of the text when translated from
- repository-normal format to working copy format with EOL style
- translated and keywords expanded according to the properties in the
- "properties" column of this row.
-
- NULL if this node is not a file, or is not moved here or copied here,
- or if the size has not (yet) been computed. */
- translated_size INTEGER,
-
- /* 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_rev 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,
-
- /* 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. */
- copyfrom_repos_id INTEGER REFERENCES REPOSITORY (id),
- copyfrom_repos_path TEXT,
- copyfrom_revnum INTEGER,
-
- /* ### JF: For an old-style move, "copyfrom" info stores its source, but a
- new WC-NG "move" is intended to be a "true rename" so its copyfrom
- revision is implicit, being in effect (new head - 1) at commit time.
- For a (new) move, we need to store or deduce the copyfrom local-relpath;
- perhaps add a column called "moved_from". */
-
- /* Boolean value, specifying if this node was moved here (rather than just
- copied). The source of the move is specified in copyfrom_*. */
- moved_here INTEGER,
-
- /* If the underlying node was moved away (rather than just deleted), this
- specifies the local_relpath of where the BASE node was moved to.
- This is set only on the root of a move, and is NULL for all children.
-
- Note that moved_to never refers to *this* node. It always refers
- to the "underlying" node, whether that is BASE or a child node
- implied from a parent's move/copy. */
- moved_to TEXT,
-
- /* ### Do we need this? We've currently got various mod time APIs
- ### internal to libsvn_wc, but those might be used in answering some
- ### question which is better answered some other way. */
- last_mod_time INTEGER, /* an APR date/time (usec since 1970) */
-
- /* serialized skel of this node's properties. NULL if we
- have no information about the properties (a non-present node). */
- properties BLOB,
-
- /* should the node on disk be kept after a schedule delete?
-
- ### Bert points out that this can disappear once we get to single-db.
- ### The entire reason for this flag to exist is
- ### so that the admin area can exist for the commit of a delete,
- ### and so the post-commit cleanup knows not to actually delete the dir
- ### from disk (which is why the flag is only ever set on the this_dir
- ### entry in WC-OLD.) With single-db, we don't need to keep the old
- ### admin area around, so this flag can disappear.
- ### neels: In contrast, the --keep-local commandline option will not
- ### disappear. The user will still be able to do
- ### 'svn delete --keep-local' and keep the to-be-unversioned paths
- ### in the file system. It just won't be necessary to remember the
- ### keep-local-ness here, because we either delete the file system paths
- ### right away during 'svn delete' or we don't at all. There won't be a
- ### "second pass" for file system deletion at commit time anymore. */
- keep_local INTEGER,
-
- PRIMARY KEY (wc_id, local_relpath)
- );
-
-CREATE INDEX I_WORKING_PARENT ON WORKING_NODE (wc_id, parent_relpath);
-
-
-/* ------------------------------------------------------------------------- */
-
-/* The ACTUAL_NODE table describes text changes and property changes on each
- node in the WC, relative to the WORKING_NODE table row for the same path
- (if present) or else to the BASE_NODE row for the same path. (Either a
- WORKING_NODE row or a BASE_NODE row must exist if this node exists, but
- an ACTUAL_NODE row can exist on its own if it is just recording info on
- a non-present node - a tree conflict or a changelist, for example.)
+/* The ACTUAL_NODE table describes text changes and property changes
+ on each node in the WC, relative to the NODES table row for the
+ same path. (A NODES row must exist if this node exists, but an
+ ACTUAL_NODE row can exist on its own if it is just recording info
+ on a non-present node - a tree conflict or a changelist, for
+ example.)
The ACTUAL_NODE table row for a given path exists if the node at that
path is known to have text or property changes relative to its
- WORKING_NODE row. ("Is known" because a text change on disk may not yet
+ NODES row. ("Is known" because a text change on disk may not yet
have been discovered and recorded here.)
The ACTUAL_NODE table row for a given path may also exist in other cases,
@@ -732,8 +334,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,15 +357,12 @@ 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. */
- presence TEXT NOT NULL,
+ which), and has not been replaced.
- /* 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,
+ excluded: this node is administratively excluded (sparse WC). This must
+ be a child (or grandchild etc.) of a copied directory.
+ */
+ presence TEXT NOT NULL,
/* ### JF: For an old-style move, "copyfrom" info stores its source, but a
new WC-NG "move" is intended to be a "true rename" so its copyfrom
@@ -784,27 +383,42 @@ CREATE TABLE NODES (
implied from a parent's move/copy. */
moved_to TEXT,
- /* Repository state fields */
+
+ /* Content fields */
/* 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.
+ /* serialized skel of this node's properties. NULL if we
+ have no information about the properties (a non-present node). */
+ properties BLOB,
- 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,
- /* serialized skel of this node's properties. NULL if we
- have no information about the properties (a non-present node). */
- properties BLOB,
+ /* for kind==symlink, this specifies the target. */
+ symlink_target TEXT,
+
+
+ /* Last-Change fields */
+
+ /* If this node was moved here or copied here, then the following fields may
+ have information about their source node. changed_rev must be not-null
+ if this node has presence=="normal". changed_date and changed_author may
+ be null if the corresponding revprops are missing.
+
+ 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,
/* Various cache fields */
@@ -833,9 +447,6 @@ CREATE TABLE NODES (
node does not have any dav-cache. */
dav_cache BLOB,
- /* for kind==symlink, this specifies the target. */
- symlink_target TEXT,
-
/* The serialized file external information. */
/* ### hack. hack. hack.
### This information is already stored in properties, but because the
@@ -853,8 +464,7 @@ CREATE TABLE NODES (
);
-CREATE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath);
-CREATE INDEX I_NODES_PATH ON NODES (wc_id, local_relpath);
+CREATE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, op_depth);
@@ -977,6 +587,45 @@ PRAGMA user_version = 17;
-- STMT_UPGRADE_TO_18
PRAGMA user_version = 18;
+
+/* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */
+
+-- STMT_UPGRADE_TO_20
+
+INSERT INTO NODES (
+ wc_id, local_relpath, op_depth, parent_relpath,
+ repos_id, repos_path, revision,
+ presence, depth, moved_here, moved_to, kind,
+ changed_revision, changed_date, changed_author,
+ checksum, properties, translated_size, last_mod_time,
+ dav_cache, symlink_target, file_external )
+SELECT wc_id, local_relpath, 0 AS op_depth, parent_relpath,
+ repos_id, repos_relpath, revnum,
+ presence, depth, NULL AS moved_here, NULL AS moved_to, kind,
+ changed_rev, changed_date, changed_author,
+ checksum, properties, translated_size, last_mod_time,
+ dav_cache, symlink_target, file_external
+FROM BASE_NODE;
+INSERT INTO NODES (
+ wc_id, local_relpath, op_depth, parent_relpath,
+ repos_id, repos_path, revision,
+ presence, depth, moved_here, moved_to, kind,
+ changed_revision, changed_date, changed_author,
+ checksum, properties, translated_size, last_mod_time,
+ dav_cache, symlink_target, file_external )
+SELECT wc_id, local_relpath, 2 AS op_depth, parent_relpath,
+ copyfrom_repos_id, copyfrom_repos_path, copyfrom_revnum,
+ presence, depth, NULL AS moved_here, NULL AS moved_to, kind,
+ changed_rev, changed_date, changed_author,
+ checksum, properties, translated_size, last_mod_time,
+ NULL AS dav_cache, symlink_target, NULL AS file_external
+FROM WORKING_NODE;
+
+DROP TABLE BASE_NODE;
+DROP TABLE WORKING_NODE;
+
+PRAGMA user_version = 20;
+
/* ------------------------------------------------------------------------- */
/* Format YYY introduces new handling for conflict information. */
@@ -991,81 +640,6 @@ PRAGMA user_version = 18;
number will be, however, so we're just marking it as 99 for now. */
-- format: 99
-/* We cannot directly remove columns, so we use a temporary table instead. */
-/* First create the temporary table without the undesired column(s). */
-CREATE TEMPORARY TABLE BASE_NODE_BACKUP(
- wc_id INTEGER NOT NULL,
- local_relpath TEXT NOT NULL,
- repos_id INTEGER,
- repos_relpath TEXT,
- parent_relpath TEXT,
- presence TEXT NOT NULL,
- kind TEXT NOT NULL,
- revnum INTEGER,
- checksum TEXT,
- translated_size INTEGER,
- changed_rev INTEGER,
- changed_date INTEGER,
- changed_author TEXT,
- depth TEXT,
- symlink_target TEXT,
- last_mod_time INTEGER,
- properties BLOB,
- dav_cache BLOB,
- file_external TEXT
-);
-
-/* Copy everything into the temporary table. */
-INSERT INTO BASE_NODE_BACKUP SELECT
- wc_id, local_relpath, repos_id, repos_relpath, parent_relpath, presence,
- kind, revnum, checksum, translated_size, changed_rev, changed_date,
- changed_author, depth, symlink_target, last_mod_time, properties, dav_cache,
- file_external
-FROM BASE_NODE;
-
-/* Drop the original table. */
-DROP TABLE BASE_NODE;
-
-/* Recreate the original table, this time less the temporary columns.
- Column descriptions are same as BASE_NODE in format 12 */
-CREATE TABLE BASE_NODE(
- wc_id INTEGER NOT NULL REFERENCES WCROOT (id),
- local_relpath TEXT NOT NULL,
- repos_id INTEGER REFERENCES REPOSITORY (id),
- repos_relpath TEXT,
- parent_relpath TEXT,
- presence TEXT NOT NULL,
- kind TEXT NOT NULL,
- revnum INTEGER,
- checksum TEXT,
- translated_size INTEGER,
- changed_rev INTEGER,
- changed_date INTEGER,
- changed_author TEXT,
- depth TEXT,
- symlink_target TEXT,
- last_mod_time INTEGER,
- properties BLOB,
- dav_cache BLOB,
- file_external TEXT,
-
- PRIMARY KEY (wc_id, local_relpath)
- );
-
-/* Recreate the index. */
-CREATE INDEX I_PARENT ON BASE_NODE (wc_id, parent_relpath);
-
-/* Copy everything back into the original table. */
-INSERT INTO BASE_NODE SELECT
- wc_id, local_relpath, repos_id, repos_relpath, parent_relpath, presence,
- kind, revnum, checksum, translated_size, changed_rev, changed_date,
- changed_author, depth, symlink_target, last_mod_time, properties, dav_cache,
- file_external
-FROM BASE_NODE_BACKUP;
-
-/* Drop the temporary table. */
-DROP TABLE BASE_NODE_BACKUP;
-
/* Now "drop" the tree_conflict_data column from actual_node. */
CREATE TABLE ACTUAL_NODE_BACKUP (
wc_id INTEGER NOT NULL,